#include <bits/stdc++.h>
using namespace std;
const long long INF = 1e15;
const long long MAXN = 300005;
const long long MAX_V = MAXN;
struct edge {
  int v1, v2;
  bool operator<(const edge &o) const {
    if (v1 == o.v1) return v2 < o.v2;
    return v1 < o.v1;
  }
};
int N, M, K;
int DADDY[MAXN];
vector<pair<int, int> > G[MAXN];
long long dist[MAXN];
void dijkstra(int x) {
  memset(dist, -1, sizeof(dist));
  priority_queue<pair<long long, int> > q;
  dist[x] = 0;
  q.push(make_pair(0, x));
  while (!q.empty()) {
    x = q.top().second;
    long long c = -q.top().first;
    q.pop();
    if (dist[x] != c) continue;
    for (int i = (0); i < int(G[x].size()); i++) {
      int y = G[x][i].first, c = G[x][i].second;
      if (dist[y] < 0 || dist[x] + c < dist[y]) {
        dist[y] = dist[x] + c;
        q.push(make_pair(-dist[y], y));
        DADDY[y] = x;
      }
    }
  }
}
vector<int> hijitos[MAX_V];
map<edge, int> EdgeInd;
bool USED[MAX_V];
bool VISITED[MAX_V];
vector<int> ANS;
int main() {
  scanf("%d %d %d", &N, &M, &K);
  if (K == 0) {
    printf("0\n");
    return 0;
  }
  int v1, v2, w;
  for (int i = (0); i < int(M); i++) {
    scanf("%d %d %d", &v1, &v2, &w);
    G[v1].push_back({v2, w});
    G[v2].push_back({v1, w});
    if (v1 > v2) swap(v1, v2);
    EdgeInd[{v1, v2}] = i + 1;
  }
  dijkstra(1);
  for (int i = (1); i < int(N + 1); i++)
    if (DADDY[i] > 0) hijitos[DADDY[i]].push_back(i);
  queue<int> Q;
  Q.push(1);
  int ca = K;
  while (K and Q.size()) {
    int act = Q.front();
    Q.pop();
    for (auto h : hijitos[act]) {
      v1 = act;
      v2 = h;
      if (v1 > v2) swap(v1, v2);
      ANS.push_back(EdgeInd[{v1, v2}]);
      Q.push(h);
      K--;
    }
  }
  printf("%d\n", min(int(ANS.size()), ca));
  printf("%d", ANS[0]);
  for (int i = (1); i < int(min(int(ANS.size()), ca)); i++)
    printf(" %d", ANS[i]);
  printf("\n");
  return 0;
}
