#include <bits/stdc++.h>
const long long LLINF = (1ll << 63) - 1;
const int INF = (1 << 31) - 1;
const long double PI = 3.141592653589793;
const long double EPS = 1e-15;
const unsigned long long MOD = 998244353;
const unsigned long long MOD2 = 16714589;
const int ENGLISH_ALPHABET_SIZE = 26;
const int N = 2e5 + 1;
const int M = 1e9 + 10;
using namespace std;
struct edge {
  long long to, weight, index;
  edge(long long a, long long b, long long c) : to(a), weight(b), index(c) {}
  edge() {}
};
vector<long long> dist;
vector<vector<edge>> graph;
vector<pair<long long, long long>> path;
long long m, n, k;
set<pair<long long, long long>> good;
class vertexcmp {
 public:
  inline bool operator()(const long long &a, const long long &b) const {
    if (dist[a] == dist[b]) return a < b;
    return dist[a] < dist[b];
  }
};
void dijkstra(long long v) {
  set<long long, vertexcmp> unused;
  dist[v] = 0;
  long long t = 0;
  for (int i = 0; i < n; ++i) {
    unused.insert(i);
  }
  while (!unused.empty()) {
    v = *unused.begin();
    unused.erase(unused.begin());
    for (auto e : graph[v]) {
      if (dist[v] + e.weight < dist[e.to]) {
        unused.erase(e.to);
        path[e.to] = {t++, e.index};
        dist[e.to] = dist[v] + e.weight;
        unused.insert(e.to);
      }
    }
  }
  for (int i = 0; i < n; ++i)
    if (path[i].first >= 0) good.insert(path[i]);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin >> n >> m >> k;
  dist.resize(n, LLINF);
  graph.resize(n, vector<edge>());
  path.resize(n, {-1, -1});
  for (long long i = 0, a, b, w; i < m; ++i) {
    cin >> a >> b >> w;
    a--, b--;
    graph[a].push_back(edge(b, w, i + 1));
    graph[b].push_back(edge(a, w, i + 1));
  }
  dijkstra(0);
  cout << min(k, (long long)good.size()) << endl;
  for (auto e : good) {
    if (!k) break;
    cout << e.second << " ";
    k--;
  }
  return 0;
}
