Chouti was tired of the tedious homework, so he opened up an old programming problem he created years ago.

You are given a connected undirected graph with $n$ vertices and $m$ weighted edges. There are $k$ special vertices: $x_1, x_2, \ldots, x_k$.

Let's define the cost of the path as the maximum weight of the edges in it. And the distance between two vertexes as the minimum cost of the paths connecting them.

For each special vertex, find another special vertex which is farthest from it (in terms of the previous paragraph, i.e. the corresponding distance is maximum possible) and output the distance between them.

The original constraints are really small so he thought the problem was boring. Now, he raises the constraints and hopes you can solve it for him.


-----Input-----

The first line contains three integers $n$, $m$ and $k$ ($2 \leq k \leq n \leq 10^5$, $n-1 \leq m \leq 10^5$) — the number of vertices, the number of edges and the number of special vertices.

The second line contains $k$ distinct integers $x_1, x_2, \ldots, x_k$ ($1 \leq x_i \leq n$).

Each of the following $m$ lines contains three integers $u$, $v$ and $w$ ($1 \leq u,v \leq n, 1 \leq w \leq 10^9$), denoting there is an edge between $u$ and $v$ of weight $w$. The given graph is undirected, so an edge $(u, v)$ can be used in the both directions.

The graph may have multiple edges and self-loops.

It is guaranteed, that the graph is connected.


-----Output-----

The first and only line should contain $k$ integers. The $i$-th integer is the distance between $x_i$ and the farthest special vertex from it.


-----Examples-----
Input
2 3 2
2 1
1 2 3
1 2 2
2 2 1

Output
2 2 

Input
4 5 3
1 2 3
1 2 5
4 2 1
2 3 2
1 4 4
1 3 3

Output
3 3 3 



-----Note-----

In the first example, the distance between vertex $1$ and $2$ equals to $2$ because one can walk through the edge of weight $2$ connecting them. So the distance to the farthest node for both $1$ and $2$ equals to $2$.

In the second example, one can find that distance between $1$ and $2$, distance between $1$ and $3$ are both $3$ and the distance between $2$ and $3$ is $2$.

The graph may have multiple edges between and self-loops, as in the first example.

Difficulty: interview

Starter code:

Solutions:
def g():
 return list(map(int,input().split()))
n,m,k=g()
p=list(range(n+1))
z=[0]*(n+1)
for x in g():
 z[x]=1
e=[]
for i in range(m):
 u,v,w=g()
 e+=[(w,u,v)]
e=sorted(e)
def q(x):
 if x!=p[x]:
  p[x]=q(p[x])
 return p[x]
for w,u,v in e:
 u=q(u);v=q(v)
 if u!=v:
  if u%5==3:
   u,v=v,u
  p[u]=v;z[v]+=z[u]
  if z[v]==k:
   print(((str(w)+' ')*k));return


import sys
import heapq
from collections import deque

n,m,k=list(map(int,sys.stdin.readline().split()))
X=list(map(int,sys.stdin.readline().split()))
start=X[0]

EDGE=[list(map(int,sys.stdin.readline().split())) for i in range(m)]
COST_vertex=[[] for i in range(n+1)]
for i,j,w in EDGE:
    COST_vertex[i].append((j,w))
    COST_vertex[j].append((i,w))
    

MINCOST=[float("inf")]*(n+1)#求めたいリスト:startから頂点iへの最短距離
MINCOST[start]=0
checking=[(0,start)]#start時点のcostは0.最初はこれをチェックする.
while checking:
    cost,checktown=heapq.heappop(checking)
    #cost,checktownからの行き先をcheck.
    #cost最小なものを確定し,確定したものはcheckingから抜く.
    if MINCOST[checktown]<cost:#確定したものを再度チェックしなくて良い.
        continue    
    for to,co in COST_vertex[checktown]:
        if MINCOST[to]>max(MINCOST[checktown],co):
            MINCOST[to]=max(MINCOST[checktown],co)
            #MINCOST候補に追加
            heapq.heappush(checking,(max(MINCOST[checktown],co),to))


ANSLIST=[MINCOST[X[i]] for i in range(1,k)]

ANS=(str(max(ANSLIST))+" ")*k

sys.stdout.write(str(ANS)+"\n")
    



import sys
import heapq
from collections import deque

n,m,k=list(map(int,sys.stdin.readline().split()))
X=list(map(int,sys.stdin.readline().split()))
start=X[0]

EDGE=[list(map(int,sys.stdin.readline().split())) for i in range(m)]
COST_vertex=[[] for i in range(n+1)]
for i,j,w in EDGE:
    COST_vertex[i].append((j,w))
    COST_vertex[j].append((i,w))
    

MINCOST=[float("inf")]*(n+1)#求めたいリスト:startから頂点iへの最短距離
MINCOST[start]=0
checking=[(0,start)]#start時点のcostは0.最初はこれをチェックする.
while checking:
    cost,checktown=heapq.heappop(checking)
    #cost,checktownからの行き先をcheck.
    #cost最小なものを確定し,確定したものはcheckingから抜く.
    if MINCOST[checktown]<cost:#確定したものを再度チェックしなくて良い.
        continue    
    for to,co in COST_vertex[checktown]:
        if MINCOST[to]>max(MINCOST[checktown],co):
            MINCOST[to]=max(MINCOST[checktown],co)
            #MINCOST候補に追加
            heapq.heappush(checking,(max(MINCOST[checktown],co),to))


ANSLIST=[MINCOST[X[i]] for i in range(1,k)]

ANS=(str(max(ANSLIST))+" ")*k

sys.stdout.write(str(ANS)+"\n")
    



import sys
sys.setrecursionlimit(300000)
n,m,k=list(map(int,input().split()))
x=list(map(int,input().split()))
edges=[]
for i in range(m):
    a,b,c=list(map(int,input().split()))
    edges.append((c,a,b))
edges.sort()
tree=[i for i in range(n+1)]
used=[]
edgess=0
def q(x):
    if x!=tree[x]:
        tree[x]=q(tree[x])
    return(tree[x])
for w,u,v in edges:
    if edgess==n-1:
        break
    a,b=q(u),q(v)
    if a%2==1:
        a,b=b,a
    if a!=b:
        tree[a]=b
        used.append((w,u,v))
        edgess+=1
neigh=[]
for i in range(n+1):
    neigh.append([])
for w,u,v in used:
    neigh[u].append((v,w))
    neigh[v].append((u,w))
layer=[x[0]]
pars=[None]
dists=[None]*(n+1)
dists[x[0]]=0
while layer!=[]:
    newlayer=[]
    newpars=[]
    for i in range(len(layer)):
        guy=layer[i]
        par=pars[i]
        for v,w in neigh[guy]:
            if v!=par:
                dists[v]=max(dists[guy],w)
                newlayer.append(v)
                newpars.append(guy)
    layer=newlayer
    pars=newpars
high=0
for guy in x:
    high=max(high,dists[guy])
print((str(high)+" ")*k)


import sys
def int_reader():
    yield from (int(d) for d in sys.stdin.read().split())

ints = int_reader()
n, m, k = [next(ints) for i in range(3)]
special = [next(ints) for i in range(k)]
is_special = [0]*(n+1)
for x in special:
    is_special[x] = 1

edges = []
for i in range(m):
    u, v, w = [next(ints) for j in range(3)]
    edges.append((w, u, v))
edges.sort()

fu = [i for i in range(n+1)]
def find(x):
    S = []
    while fu[x] != x:
        S.append(x)
        x = fu[x]
    for y in S:
        fu[y] = x
    return x
def union(e):
    a, b = find(e[1]), find(e[2])
    if is_special[b]:
        a, b = b, a
    fu[b] = a

ans = 0
for e in edges:
    a, b = find(e[1]), find(e[2])
    if a == b: continue
    if is_special[a] and is_special[b]:
        ans = e[0]
    union(e)
print((str(ans) + ' ') * k)


import sys
def int_reader():
    yield from (int(d) for d in sys.stdin.read().split())

ints = int_reader()
n, m, k = [next(ints) for i in range(3)]
sp = {next(ints) for i in range(k)}

edges = []
for i in range(m):
    u, v, w = [next(ints) for j in range(3)]
    edges.append((w, u, v))
edges.sort()

fu = [i for i in range(n+1)]
def find(x):
    S = []
    while fu[x] != x:
        S.append(x)
        x = fu[x]
    for y in S:
        fu[y] = x
    return x
def union(a, b):
    if b in sp:
        a, b = b, a
    fu[b] = a

ans = 0
for e in edges:
    a, b = find(e[1]), find(e[2])
    if a == b: continue
    if a in sp and b in sp:
        ans = e[0]
    union(a, b)
print((str(ans) + ' ') * k)


n, m, k = map(int, input().split())
x = list(map(int, input().split()))
e = []
for _ in range(m) :
    e.append(tuple(map(int, input().split())))
e.sort(key = lambda x : x[2])

fa = list(range(n + 1))
sz = [0] * (n + 1)
for u in x : sz[u] += 1

def find(x) :
    while fa[x] != x :
        fa[x] = fa[fa[x]]
        x = fa[x]
    return x

def unite(u, v) :
    u, v = map(find, (u, v))
    fa[u] = v;
    if u == v : return False
    ret = sz[u] > 0 and sz[v] > 0
    sz[v] += sz[u]
    return ret

for ed in e : 
    if unite(ed[0], ed[1]) : ans = ed[2]

print(*[ans]*k)

import sys
def int_reader():
    yield from (int(d) for d in sys.stdin.read().split())

ints = int_reader()
n, m, k = [next(ints) for i in range(3)]
sp = {next(ints) for i in range(k)}

'''
edges = []
for i in range(m):
    u, v, w = [next(ints) for j in range(3)]
    edges.append((w, u, v))
'''
edges = [(w,u,v) for (u,v,w) in [(next(ints) for i in range(3)) for j in range(m)]]
edges.sort()

fu = [i for i in range(n+1)]
def find(x):
    S = []
    while fu[x] != x:
        S.append(x)
        x = fu[x]
    for y in S:
        fu[y] = x
    return x
def union(a, b):
    if b in sp:
        a, b = b, a
    fu[b] = a

ans = 0
for e in edges:
    a, b = find(e[1]), find(e[2])
    if a == b: continue
    if a in sp and b in sp:
        ans = e[0]
    union(a, b)
print((str(ans) + ' ') * k)


# -*- coding: utf-8 -*-
"""
Created on Sun Apr 28 18:52:59 2019

@author: phamv
"""
####Function Definition 
def find(x):
    while f[x] != x :
        f[x] = f[f[x]]
        x = f[x]
    return x

def merge(u, v) :
    u, v = map(find, (u, v))
    f[u] = v;
    if u == v:
        return False
    ret = s[u] > 0 and s[v] > 0
    s[v] += s[u]
    return ret

###############

n, m, k = map(int, input().split())
x = list(map(int, input().split()))
lst = list()
for i in range(m):
    lst.append(tuple(map(int, input().split())))
lst.sort(key = lambda x: x[2])

f = list(range(n + 1))
s = [0] * (n + 1)

for j in x:
    s[j] += 1

for h in lst: 
    if merge(h[0], h[1]): 
        answer = h[2]

print(*[answer]*k)

"""
@author: phamv
"""
####Function Definition 
def find(x):
    while f[x] != x :
        f[x] = f[f[x]]
        x = f[x]
    return x

def merge(u, v) :
    u, v = map(find, (u, v))
    f[u] = v;
    if u == v:
        return False
    ret = s[u] > 0 and s[v] > 0
    s[v] += s[u]
    return ret

###############

n, m, k = map(int, input().split())
x = list(map(int, input().split()))
lst = list()
for i in range(m):
    lst.append(tuple(map(int, input().split())))
lst.sort(key = lambda x: x[2])

f = list(range(n + 1))
s = [0] * (n + 1)

for j in x:
    s[j] += 1

for h in lst: 
    if merge(h[0], h[1]): 
        answer = h[2]

print(*[answer]*k)

def g():
 return map(int,input().split())
n,m,k=g()
p=list(range(n+1))
z=[0]*(n+1)
for x in g():
 z[x]=1
e=[]
for i in range(m):
 u,v,w=g()
 e+=[(w,u,v)]
e=sorted(e)
def q(x):
 if x!=p[x]:
  p[x]=q(p[x])
 return p[x]
for w,u,v in e:
 u=q(u);v=q(v)
 if u!=v:
  if u%5==3:
   u,v=v,u
  p[u]=v;z[v]+=z[u]
  if z[v]==k:
   print((str(w)+' ')*k);return

n, m, k = map(int, input().split())
a = list(map(int, input().split()))
g = []

f = list(range(n+1))
s = [0] * (n+1)

def search(n):
    while f[n] != n:
        f[n] = f[f[n]]
        n = f[n]
    return n
def can_merge(u, v):
    u = search(u)
    v = search(v)
    f[u] = v
    if u == v:
        return False
    r = s[u] > 0 and s[v] > 0
    s[v] += s[u]
    return r

for _ in range(m):
    u,v,w = map(int, input().split())
    g.append((u,v,w))
g.sort(key = lambda tup: tup[2])

for i in a:
    s[i] += 1

ans = 0
for t in g:
    if can_merge(t[0],t[1]):
       ans = t[2]

print(' '.join([str(ans)] * k))

n, m, k = map(int, input().split())
a = list(map(int, input().split()))
g = []

f = list(range(n+1))
s = [0] * (n+1)

def search(n):
    while f[n] != n:
        f[n] = f[f[n]]
        n = f[n]
    return n
def can_merge(u, v):
    u = search(u)
    v = search(v)
    f[u] = v
    if u == v:
        return False
    r = s[u] > 0 and s[v] > 0
    s[v] += s[u]
    return r

for _ in range(m):
    u,v,w = map(int, input().split())
    g.append((u,v,w))
g.sort(key = lambda tup: tup[2])

for i in a:
    s[i] += 1

ans = 0
for t in g:
    if can_merge(t[0],t[1]):
       ans = t[2]

print(' '.join([str(ans)] * k))

n, m, k = map(int, input().split())
a = list(map(int, input().split()))
g = []

f = list(range(n+1))
s = [0] * (n+1)

def search(n):
    while f[n] != n:
        # print(f[n])

        f[n] = f[f[n]]
        n = f[n]
    return n
def can_merge(u, v):
    u = search(u)
    v = search(v)
    f[u] = v
    if u == v:
        return False
    r = s[u] > 0 and s[v] > 0
    s[v] += s[u]
    return r

for _ in range(m):
    u,v,w = map(int, input().split())
    g.append((u,v,w))
g.sort(key = lambda tup: tup[2])

for i in a:
    s[i] += 1

ans = 0
for t in g:
    if can_merge(t[0],t[1]):
       ans = t[2]

print(' '.join([str(ans)] * k))

class Union:
    def __init__(self, n, list_k):
        self.p    = {i:i for i in range(n+1)}
        self.rank = {i:0 for i in range(n+1)} 
        
        for k in list_k:
            self.rank[k] = 1
            
    def find(self, x):
        if x < 0: return x
    
        if self.p[x] != x:
            self.p[x] = self.find(self.p[x])
        return self.p[x]
    
    def union(self, x, y):
        if x < 0 or y < 0:return
        
        x = self.find(x)
        y = self.find(y)
        if x != y:
            if self.rank[x] < self.rank[y]:
                self.p[x]     = y
                self.rank[y] += self.rank[x]
            else:
                self.p[y]     = x
                self.rank[x] += self.rank[y]
                
n, m, k  = list(map(int, input().split()))
list_k   = list(map(int, input().split()))
edge  = []

for _ in range(m):
    u, v, w = list(map(int, input().split()))
    edge.append((u,v,w))
    
edge = sorted(edge, key=lambda x:x[2])

U   = Union(n, list_k)
val = 0

for u, v, w in edge:
    if u == v: continue
        
    par_1 =  U.find(u)
    par_2 =  U.find(v)    
        
    if par_1 == par_2:
        continue
        
    if U.rank[par_1] + U.rank[par_2] == k:
        val = w
        break
    
    U.union(u, v)

s = ''
for _ in  range(len(list_k)):
    s += str(val) + ' '    
                
print(s)
                
#2 3 2
#2 1
#1 2 3
#1 2 2
#2 2 1


import sys
input = sys.stdin.readline

# def find(a):
#     if par[a] == a:
#         return a
#     par[a] = find(par[a])
#     return par[a]

def find(a):
    upd = []
    cur = a
    while par[cur] != cur:
        upd.append(cur)
        cur = par[cur]
    for x in upd:
        par[x] = cur
    return cur

def union(a, b):
    a = find(a)
    b = find(b)
    if a == b:
        return
    par[a] = b


def mst():
    ret = []
    for edge in edges:
        u, v, w = edge
        u = find(u)
        v = find(v)
        if u != v:
            union(u, v)
            ret.append(edge)
    return ret


def dfs(u, par):
    for v, w in adj[u]:
        if v != par:
            dist[v] = max(dist[u], w)
            dfs(v, u)

def bfs(u):
    visit = [False] * (n+1)
    from collections import deque

    dq = deque()
    dq.append(u)
    visit[u] = True
    while dq:
        u = dq.popleft()
        for v, w in adj[u]:
            if not visit[v]:
                dist[v] = max(dist[u], w)
                dq.append(v)
                visit[v] = True


n, m, k = list(map(int, input().split()))
a = list(map(int, input().split()))
# n = 50000
# m = 2 * n
# k = n
# a = [i for i in range(1, n+1)]
# import random

par = [0] * (n+1)
for i in range(1, n+1):
    par[i] = i
edges = []
# for i in range(1, n+1):
#     edge = (i, 1 if i+1 > n else i+1, random.randint(1, 1000000000))
#     edge = (i, 1 if i+2 > n else i+2, random.randint(1, 1000000000))
#     edges.append(edge)
for i in range(m):
    edge = tuple(map(int, input().split()))
    edges.append(edge)
edges.sort(key=lambda x: x[2])
edges = mst()
adj = [list() for i in range(n+1)]
for edge in edges:
    u, v, w = edge
    adj[u].append((v, w))
    adj[v].append((u, w))

dist = [0] * (n+1)
# dfs(a[0], -1)
bfs(a[0])
ans = 0
for x in a:
    ans = max(ans, dist[x])
ans = [ans] * k
print(*ans)



def main():
    import sys
    input = sys.stdin.readline
    
    # def find(a):
    #     if par[a] == a:
    #         return a
    #     par[a] = find(par[a])
    #     return par[a]
    
    def find(a):
        upd = []
        cur = a
        while par[cur] != cur:
            upd.append(cur)
            cur = par[cur]
        for x in upd:
            par[x] = cur
        return cur
    
    def union(a, b):
        a = find(a)
        b = find(b)
        if a == b:
            return
        par[a] = b
    
    
    def mst():
        ret = []
        for edge in edges:
            u, v, w = edge
            u = find(u)
            v = find(v)
            if u != v:
                union(u, v)
                ret.append(edge)
        return ret
    
    
    def dfs(u, par):
        for v, w in adj[u]:
            if v != par:
                dist[v] = max(dist[u], w)
                dfs(v, u)
    
    def bfs(u):
        visit = [False] * (n+1)
        from collections import deque
    
        dq = deque()
        dq.append(u)
        visit[u] = True
        while dq:
            u = dq.popleft()
            for v, w in adj[u]:
                if not visit[v]:
                    dist[v] = max(dist[u], w)
                    dq.append(v)
                    visit[v] = True
    
    
    n, m, k = map(int, input().split())
    a = list(map(int, input().split()))
    # n = 50000
    # m = 2 * n
    # k = n
    # a = [i for i in range(1, n+1)]
    # import random
    
    par = [0] * (n+1)
    for i in range(1, n+1):
        par[i] = i
    edges = []
    # for i in range(1, n+1):
    #     edge = (i, 1 if i+1 > n else i+1, random.randint(1, 1000000000))
    #     edge = (i, 1 if i+2 > n else i+2, random.randint(1, 1000000000))
    #     edges.append(edge)
    for i in range(m):
        edge = tuple(map(int, input().split()))
        edges.append(edge)
    edges.sort(key=lambda x: x[2])
    edges = mst()
    adj = [list() for i in range(n+1)]
    for edge in edges:
        u, v, w = edge
        adj[u].append((v, w))
        adj[v].append((u, w))
    
    dist = [0] * (n+1)
    # dfs(a[0], -1)
    bfs(a[0])
    ans = 0
    for x in a:
        ans = max(ans, dist[x])
    ans = [ans] * k
    print(*ans)
    

main()

def main():
    import sys
    input = sys.stdin.readline

    # def find(a):
    #     if par[a] == a:
    #         return a
    #     par[a] = find(par[a])
    #     return par[a]

    def find(a):
        upd = []
        cur = a
        while par[cur] != cur:
            upd.append(cur)
            cur = par[cur]
        for x in upd:
            par[x] = cur
        return cur

    def union(a, b):
        a = find(a)
        b = find(b)
        if a == b:
            return
        if height[b] > height[a]:
            a, b = b, a
        par[b] = a
        if height[a] == height[b]:
            height[a] += 1


    def mst():
        ret = []
        for edge in edges:
            u, v, w = edge
            u = find(u)
            v = find(v)
            if u != v:
                union(u, v)
                ret.append(edge)
        return ret


    def dfs(u, par):
        for v, w in adj[u]:
            if v != par:
                dist[v] = max(dist[u], w)
                dfs(v, u)

    def bfs(u):
        visit = [False] * (n+1)
        from collections import deque

        dq = deque()
        dq.append(u)
        visit[u] = True
        while dq:
            u = dq.popleft()
            for v, w in adj[u]:
                if not visit[v]:
                    dist[v] = max(dist[u], w)
                    dq.append(v)
                    visit[v] = True


    n, m, k = map(int, input().split())
    a = list(map(int, input().split()))
    # n = 50000
    # m = 2 * n
    # k = n
    # a = [i for i in range(1, n+1)]
    # import random

    par = [0] * (n+1)
    height = [1] * (n+1)
    for i in range(1, n+1):
        par[i] = i
        height[i] = 1
    edges = []
    # for i in range(1, n+1):
    #     edge = (i, 1 if i+1 > n else i+1, random.randint(1, 1000000000))
    #     edge = (i, 1 if i+2 > n else i+2, random.randint(1, 1000000000))
    #     edges.append(edge)
    for i in range(m):
        edge = tuple(map(int, input().split()))
        edges.append(edge)
    edges.sort(key=lambda x: x[2])
    edges = mst()
    adj = [list() for i in range(n+1)]
    for edge in edges:
        u, v, w = edge
        adj[u].append((v, w))
        adj[v].append((u, w))

    dist = [0] * (n+1)
    # dfs(a[0], -1)
    bfs(a[0])
    ans = 0
    for x in a:
        ans = max(ans, dist[x])
    ans = [ans] * k
    print(*ans)


main()

def main():
    import sys
    input = sys.stdin.readline

    # def find(a):
    #     if par[a] == a:
    #         return a
    #     par[a] = find(par[a])
    #     return par[a]

    def find(a):
        upd = []
        cur = a
        while par[cur] != cur:
            upd.append(cur)
            cur = par[cur]
        for x in upd:
            par[x] = cur
        return cur

    def union(a, b):
        a = find(a)
        b = find(b)
        if a == b:
            return
        par[b] = a


    def mst():
        ret = []
        for edge in edges:
            u, v, w = edge
            u = find(u)
            v = find(v)
            if u != v:
                union(u, v)
                ret.append(edge)
        return ret


    def dfs(u, par):
        for v, w in adj[u]:
            if v != par:
                dist[v] = max(dist[u], w)
                dfs(v, u)

    def bfs(u):
        visit = [False] * (n+1)
        from collections import deque

        dq = deque()
        dq.append(u)
        visit[u] = True
        while dq:
            u = dq.popleft()
            for v, w in adj[u]:
                if not visit[v]:
                    dist[v] = max(dist[u], w)
                    dq.append(v)
                    visit[v] = True


    n, m, k = map(int, input().split())
    a = list(map(int, input().split()))
    # n = 50000
    # m = 2 * n
    # k = n
    # a = [i for i in range(1, n+1)]
    # import random

    par = [0] * (n+1)
    for i in range(1, n+1):
        par[i] = i
    edges = []
    # for i in range(1, n+1):
    #     edge = (i, 1 if i+1 > n else i+1, random.randint(1, 1000000000))
    #     edge = (i, 1 if i+2 > n else i+2, random.randint(1, 1000000000))
    #     edges.append(edge)
    for i in range(m):
        edge = tuple(map(int, input().split()))
        edges.append(edge)
    edges.sort(key=lambda x: x[2])
    edges = mst()
    adj = [list() for i in range(n+1)]
    for edge in edges:
        u, v, w = edge
        adj[u].append((v, w))
        adj[v].append((u, w))

    dist = [0] * (n+1)
    # dfs(a[0], -1)
    bfs(a[0])
    ans = 0
    for x in a:
        ans = max(ans, dist[x])
    ans = [ans] * k
    print(*ans)


main()

import sys
sys.setrecursionlimit(300000)
n,m,k=list(map(int,input().split()))
x=list(map(int,input().split()))
edges=[]
for i in range(m):
    a,b,c=list(map(int,input().split()))
    edges.append((c,a,b))
edges.sort()
tree=[i for i in range(n+1)]
used=[]
edgess=0
def q(x):
    if x!=tree[x]:
        tree[x]=q(tree[x])
    return(tree[x])
for w,u,v in edges:
    if edgess==n-1:
        break
    a,b=q(u),q(v)
    if a%2==1:
        a,b=b,a
    if a!=b:
        tree[a]=b
        used.append((w,u,v))
        edgess+=1
neigh=[]
for i in range(n+1):
    neigh.append([])
for w,u,v in used:
    neigh[u].append((v,w))
    neigh[v].append((u,w))
layer=[x[0]]
pars=[None]
dists=[None]*(n+1)
dists[x[0]]=0
while layer!=[]:
    newlayer=[]
    newpars=[]
    for i in range(len(layer)):
        guy=layer[i]
        par=pars[i]
        for v,w in neigh[guy]:
            if v!=par:
                dists[v]=max(dists[guy],w)
                newlayer.append(v)
                newpars.append(guy)
    layer=newlayer
    pars=newpars
high=0
for guy in x:
    high=max(high,dists[guy])
print((str(high)+" ")*k)


import sys
input = sys.stdin.readline


n, m, k = list(map(int, input().split()))
x = list(map(int, input().split()))

uf = [-1 for _ in range(n+1)]


def find(p, uf):
    if uf[p] < 0:
        return p
    uf[p] = find(uf[p], uf)
    return uf[p]


def union(p, q, uf, specials):
    proot = find(p, uf)
    qroot = find(q, uf)
    if proot == qroot:
        return
    elif uf[proot] > uf[qroot]:
        uf[qroot] += uf[proot]
        uf[proot] = qroot
        specials[qroot] = specials[qroot] or specials[proot]
    else:
        uf[proot] += uf[qroot]
        uf[qroot] = proot
        specials[proot] = specials[qroot] or specials[proot]


edges = []
for _ in range(m):
    u, v, w = list(map(int, input().split()))
    edges.append((w, u, v))
edges = sorted(edges, key=lambda item: item[0])
specials = [0] * (n + 1)
for item in x:
    specials[item] = 1
#special_edges = []
ans = -1
for w, u, v in edges:
    ufather, vfather = find(u, uf), find(v, uf)
    if ufather != vfather:
        if specials[ufather] == 1 and specials[vfather] == 1:
            #special_edges.append((w, u, v))
            ans = max(ans, w)
        union(u, v, uf, specials)
#special_edges = sorted(special_edges, key=lambda item:item[0])

res = [ans] * k
print(' '.join(map(str, res)))


import sys
input = sys.stdin.readline

n, m, k = list(map(int, input().split()))
x = list(map(int, input().split()))

uf = [-1 for _ in range(n+1)]

def find(p, uf):
    if uf[p] < 0:
        return p
    uf[p] = find(uf[p], uf)
    return uf[p]

def union(p, q, uf, specials):
    proot = find(p, uf)
    qroot = find(q, uf)
    if proot == qroot:
        return
    elif uf[proot] > uf[qroot]:
        uf[qroot] += uf[proot]
        uf[proot] = qroot
        specials[qroot] = specials[qroot] or specials[proot]
    else:
        uf[proot] += uf[qroot]
        uf[qroot] = proot
        specials[proot] = specials[qroot] or specials[proot]

edges = []
for _ in range(m):
    u, v, w = list(map(int, input().split()))
    edges.append((w, u, v))
edges = sorted(edges, key=lambda item: item[0])
specials = [0] * (n + 1)
for item in x:
    specials[item] = 1

ans = -1
for w, u, v in edges:
    ufather, vfather = find(u, uf), find(v, uf)
    if ufather != vfather:
        if specials[ufather] == 1 and specials[vfather] == 1:
            ans = max(ans, w)
        union(u, v, uf, specials)

res = [ans] * k
print(' '.join(map(str, res)))


def put():
    return list(map(int, input().split()))

def find(i):
    if i == p[i]:
        return i
    p[i]=find(p[i])
    return p[i]

def union(i,j):
    if rank[i]<rank[j]:
        i,j = j,i
    elif rank[i]==rank[j]:
        rank[i]+=1
    p[j]=i
    z[i]+=z[j]
    return z[i]

n,m,k =put()
l = list(put())
z,edge,p,rank = [0]*(n+1), [], list(range(n+1)), [0]*(n+1)

for i in l:
    z[i]=1
for i in range(m):
    u,v,w = put()
    edge.append((w,u,v))
edge.sort()

for w,u,v in edge:
    u,v = list(map(find, (u,v)))
    if u!=v:
        cnt=union(u,v)
        if cnt==k:
            print((str(w)+' ')*k)
            break