#include <bits/stdc++.h>
#define BIT(n) (1LL << (n))
#define BITF(n, i) (((n) >> i) & 1)
#define REP(i, n) for (int i = 0; i < n; i++)
#define REPB(i, n) for (int i = 0; i < BIT(n); i++)
#define REPS(i, x) for (int i = 1; i <= x; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define REPZ(i, x) for (int i = 0; i <= x; i++)
#define FOR(i, m, n) for (int i = m; i < n; i++)
#define FORA(i, n) for (auto &&i : n)
#define FORS(i, m, n) for (int i = m; i <= n; i++)
#define PRINTARR(x, y)                                     \
  cerr << #x << "=\n";                                     \
  for (auto itr = x; itr != y; itr++) cerr << *itr << " "; \
  cerr << endl;
#define PRINTARR2(x, i0, i1)                                       \
  cerr << #x << "=\n";                                             \
  for (int ii0 = 0; ii0 < i0; ii0++) {                             \
    for (int ii1 = 0; ii1 < i1; ii1++) cerr << x[ii0][ii1] << " "; \
    cerr << endl;                                                  \
  }
using namespace std;
#define DUMPOUT cerr
// vector
template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  for (T &x : vec) is >> x;
  return is;
}
// pair
template <typename T, typename U> ostream &operator<<(ostream &os, pair<T, U> &pair_var) {
  os << "(" << pair_var.first << ", " << pair_var.second << ")";
  return os;
}
// vector
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "{";
  REP(i, (int)vec.size())
  os << vec[i] << (i + 1 == (int)vec.size() ? "" : ", ");
  os << "}";
  return os;
}
// map
template <typename T, typename U> ostream &operator<<(ostream &os, map<T, U> &map_var) {
  os << "{";
  FORA(itr, map_var) {
    os << *itr;
    itr++;
    if (itr != map_var.end()) os << ", ";
    itr--;
  }
  os << "}";
  return os;
}
// set
template <typename T> ostream &operator<<(ostream &os, set<T> &set_var) {
  os << "{";
  FORA(itr, set_var) {
    os << *itr;
    itr++;
    if (itr != set_var.end()) os << ", ";
    itr--;
  }
  os << "}";
  return os;
}
void dump_func() { DUMPOUT << endl; }
template <class Head, class... Tail> void dump_func(Head &&head, Tail &&... tail) {
  DUMPOUT << head;
  if (sizeof...(Tail) > 0) DUMPOUT << ", ";
  dump_func(std::move(tail)...);
}
#ifdef DEBUG_
#define DEB
#define DUMP(...)                                                             \
  DUMPOUT << "  " << string(#__VA_ARGS__) << ": "                             \
          << "[" << to_string(__LINE__) << ":" << __FUNCTION__ << "]" << endl \
          << "    ",                                                          \
      dump_func(__VA_ARGS__)
#else
#define DEB if (false)
#define DUMP(...)
#endif

#define ALL(v) v.begin(), v.end()
#define fst first
#define snd second
#define mp make_pair
#define pb push_back
#define epb emplace_back
#define pint pair<int, int>
#define ld long double
using namespace std;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> using vec = std::vector<T>;
template <class T> void print(const T &x) { cout << x << "\n"; }
#define ll long long
const int MOD = 1000000007, INF = 1061109567;
const ll INF2 = (ll)INF * (ll)INF;
const double EPS = 1e-10, PI = acos(-1.0);
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};

#define MAXN 400
#define MAXG 40  // 100001/14
#define MAXCITY 16
#define MAX2N 800
#define CALCTIME(s0, s1, TT) s1 = chrono::system_clock::now(), TT = static_cast<double>(chrono::duration_cast<chrono::microseconds>(s1 - s0).count() / 1000000.0);
#define TESTA
chrono::system_clock::time_point s0, s1;
//----//
struct edge {
  int from, to, cost;
};
edge E[MAX2N];
int N, M, Tmax;
int d[MAXN][MAXN];
int Pnext[MAXN][MAXN];
int orderT[9501];         //時間ベースで見た配達の配列
int orderL[(9501 << 1)];  //配達のみの配列
int orderC[9501];         //現在の配達のみの配列
int isC[MAXN];            //現在の配達の頂点集号かどうか及び頂点のオーダーの数
// int orderD[9501];              //配達が決定した配列
int t2o[10001];       //配達のみの配列
int idG[MAXN];        //頂点番号がグループ番号が小さい順に並べてある。
int idO[(MAXG + 1)];  //グループid offset

int timeD, timeA, evalV, evalMaxV;  //出発時刻
int numO, numG, numCV;              //部分時間におけるオーダーの数 クラスタの数

int remainOrder[(10000 * 2)], remainV;  //オーダーが残っているやつとその時間
int pathAll[10001], pathN;
int pathAllG[10001], pathNG, evalNP, evalNPtmp;

bool isEndZero;
double TT;
int firstD, firstDG;
void addAndRemoveOrderList();
void assignCluster();
void ttp();
void outPath();
vec<pair<int, int>> P[MAXN][MAXN];
#define WALLTIME 29
signed main() {
  cin.tie(0), ios::sync_with_stdio(false);
  s0 = chrono::system_clock::now();
  cout << fixed << setprecision(10);

  cin >> N >> M;
  fill((int *)d, (int *)d[N], INF);
  REP(i, N) d[i][i] = 0;
  REP(i, N) REP(j, N) Pnext[i][j] = j;

  REP(i, M) {
    int p, q, r;
    cin >> p >> q >> r;
    p--, q--;
    d[p][q] = r;
    d[q][p] = r;

    E[i] = {p, q, r};
  }
  sort(E, E + M, [](const edge &a, const edge &b) { return a.cost < b.cost; });
  REP(k, N) {
    REP(i, N) {
      REP(j, N) {
        bool ff = d[i][j] > (d[i][k] + d[k][j]);
        if (ff) {
          d[i][j] = d[i][k] + d[k][j];
          Pnext[i][j] = Pnext[i][k];
        }
      }
    }
  }

  //  PRINTARR2(d, N, N);
  cin >> Tmax;
//ここからAとBの違いが現れる.
#ifdef TESTA
  int cnt = 0;
  // t2o[i]//i以降の初めての注文id
  // timeD<=x<=timeAならば　t2o[timeD]<=j<t2o[timeA+1]が範囲
  REP(i, Tmax) {
    int Nnew;
    cin >> Nnew;
    t2o[i] = cnt;
    if (Nnew) {
      int p, q;
      cin >> p >> q;
      p--, q--;
      assert(p == cnt);
      orderL[2 * p] = q;
      orderL[2 * p + 1] = i;
      orderT[i] = q;
      cnt++;
      // DUMP(i, p, q);
    }
  }
  t2o[Tmax] = cnt;

  // PRINTARR(t2o, t2o + Tmax + 1);
#endif
  //グループ分け
  numG = (N + 3) / 4;
  //偶然1によった結果　副産物として良い結果が得られる。
  //  int firstStart = 3;
  FOR(i, 0, min(5, t2o[Tmax])) {
    timeD = -1;
    timeA = orderL[2 * i + 1];
    //   timeA = 3;
    firstD = timeA;

    pathN = 0;
    evalNPtmp = 0;

    while (1) {
      isEndZero = true;
      addAndRemoveOrderList();
      assignCluster();
      //

      timeD = timeA;
      ttp();
      CALCTIME(s0, s1, TT);
      if (TT > WALLTIME) {
        outPath();
        return 0;
      }

      //      DUMP(timeA);
      if (timeA >= Tmax) break;
      if (timeA == timeD) timeA++;
    }
    // DUMP(evalNPtmp, evalNP);
    if (evalNPtmp > evalNP) {
      memcpy(pathAllG, pathAll, sizeof(pathAllG[0]) * pathN);
      evalNP = evalNPtmp;
      pathNG = pathN;
      firstDG = firstD;
    }
    // cerr << "-----------------" << endl;
    CALCTIME(s0, s1, TT);
    if (TT > WALLTIME) {
      outPath();
      return 0;
    }
  }
  outPath();
  // DUMP(TT);
}
struct cluster {
  int id, nextid, offset0, offset1, numE, idOffset;
};  // 1 4 7 | 3 6 |5 8
//評価値の計算 a,b,x (T-a-b)^2=T^2-2*(a+b)T+(a+b)^2=T^2-2*a*T+a^2-2*b*T+2*a*b+b^2
//最小時間優先なので到着を考えない
void ttpE() { return; }
// cluster idC[100];

//入力(pathAll,pathN,timeD,timeA),idG,idO
//出力 到着時刻,評価値
void ttp() {
  evalV = 0;
  // int timeV = 0;
  int timeC = timeD;
  pathAll[pathN++] = 0;
  REP(i, numG) {
    int addT = INF;
    int num = idO[i + 1] - idO[i] - 2;
    int start = idG[idO[i]];
    int end = idG[idO[i + 1] - 1];
    int neighbor = i != numG - 1 ? idG[idO[i + 1]] : end;
    assert(i != 0 || start == 0);
    //  DUMP(num, start, end, numCV, evalNPtmp, timeC);
    if (num <= 0) {
      int oldC = timeC;
      timeC += d[start][end] + d[end][neighbor];
      if (timeC >= Tmax) {
        int cnt = 0;
        bool ok = true;
        int remain = Tmax - oldC;
        pathAll[pathN++] = end;
        remain -= d[pathAll[pathN - 1]][pathAll[pathN]];
        DUMP(d[pathAll[pathN - 1]][pathAll[pathN]]);
        cnt++;
        if (remain < 0) {
          ok = false;
          break;
        }
        evalNPtmp += isC[end];
        if (ok) {
          pathAll[pathN++] = neighbor;
          remain -= d[pathAll[pathN - 1]][pathAll[pathN]];
          cnt++;
          if (remain < 0) {
            ok = false;
            break;
          }
          evalNPtmp += isC[neighbor];
        }
        break;
      } else {
        pathAll[pathN++] = end;
        evalNPtmp += isC[end];
        pathAll[pathN++] = neighbor;
        evalNPtmp += isC[neighbor];
        PRINTARR(idG + idO[i], idG + idO[i + 1]);
        DUMP(timeD, timeC, start, end, neighbor);
        PRINTARR(pathAll + pathN - num - 2, pathAll + pathN);
      }
    } else {
      int numB = (1 << num) - 1;
      int arr[MAXN];
      memcpy(arr, idG + idO[i] + 1, num * sizeof(arr[0]));
      int cost[1 << 15][15];
      int path[1 << 15][15];
      fill((int *)cost[0], (int *)cost[1 << num], INF);
      //最初のコスト加算
      REP(j, num) cost[1 << j][j] = d[start][arr[j]];
      REPS(j, numB) {  // わーシャルフロイド法　reps注意
        REP(k, num) {
          REP(l, num) {
            if (!(j >> l & 1)) {
              bool ff = cost[j | (1 << l)][l] > (cost[j][k] + d[arr[k]][arr[l]]);
              if (ff) {
                cost[j | 1 << l][l] = cost[j][k] + d[arr[k]][arr[l]];
                path[j | 1 << l][l] = k;
              }
            }
          }
        }
      }
      // PRINTARR(cost[numB], &cost[numB][num]);
      //最後のコスト加算
      int lastD = 0;
      int *ptr = cost[numB];
      REP(j, num) {
        bool ff = addT > *ptr + d[arr[j]][end];
        if (ff) {
          addT = *ptr + d[arr[j]][end];
          lastD = j;
        }
        ptr++;
      }
      //経路復元
      int pathG[20];
      pathG[0] = lastD;
      int val = numB;
      REPS(j, num - 1) {  // s 0 1 e
        pathG[j] = path[val][pathG[j - 1]];
        val = val ^ (1 << pathG[j - 1]);
      }

      int oldC = timeC;
      timeC += addT + d[end][neighbor];
      //  DUMP(timeC, Tmax);
      if (timeC >= Tmax) {
        int cnt = 0;
        bool ok = true;
        int remain = Tmax - oldC;
        //        DUMP(remain, start, end, neighbor, timeD, oldC, addT, d[end][neighbor]);
        //      PRINTARR(arr, arr + num);
        REP(j, num) {
          //  DUMP(remain, evalNPtmp);
          int val = arr[pathG[num - 1 - j]];
          pathAll[pathN++] = val;
          remain -= d[pathAll[pathN - 1]][pathAll[pathN]];
          cnt++;
          if (remain < 0) {
            ok = false;
            break;
          }
          evalNPtmp += isC[val];
        }
        if (ok) {
          //  DUMP(remain, evalNPtmp, end, isC[end]);
          pathAll[pathN++] = end;
          remain -= d[pathAll[pathN - 1]][pathAll[pathN]];
          cnt++;
          if (remain < 0) {
            ok = false;
            break;
          }
          evalNPtmp += isC[end];
        }
        if (ok) {
          // DUMP(remain, evalNPtmp);
          pathAll[pathN++] = neighbor;
          remain -= d[pathAll[pathN - 1]][pathAll[pathN]];
          cnt++;
          if (remain < 0) {
            ok = false;
            break;
          }
          evalNPtmp += isC[neighbor];
        }
        //  DUMP(cnt);
        //  PRINTARR(pathAll + pathN - cnt, pathAll + pathN);
        break;
      } else {
        REP(j, num) {
          int val = arr[pathG[num - 1 - j]];
          pathAll[pathN++] = val;
          evalNPtmp += isC[val];
        }
        pathAll[pathN++] = end;
        evalNPtmp += isC[end];
        pathAll[pathN++] = neighbor;
        evalNPtmp += isC[neighbor];
        //        PRINTARR(pathAll + pathN - num - 2, pathAll + pathN);
      }
    }
    evalV += 0;
  }
  timeA = timeC;

  evalV = 0;
  return;
}

// timeD+1<=t<=timeAを満たすorderが新たに得た配達箇所の集合.
//入力 今まで逃した配達箇所及び新たに得た配達箇所の集合 1,...,V-1
//出力 今回配達する箇所の集合 0*,1,...,V-1
void addAndRemoveOrderList() {
  fill(isC, isC + N, 0);
  //入力　出発時刻,到着時刻 timeD,timeA
  int o0 = t2o[timeA + 1] - t2o[timeD + 1];
  // DUMP(timeD, timeA, t2o[timeD + 1], t2o[timeA + 1], o0);  // t

  orderC[0] = 0;
  orderC[1] = timeA;
  isC[0] = 1;
  int *ptr1 = orderC + 2;
  int *ptr0 = remainOrder;
  //  int cnt = 0;
  /*REP(i, remainV) {
    int orderV = *ptr0++;
    int orderT = *ptr0++;
    if (1) {  //次で配達すべき
      *ptr1++ = orderV;
      *ptr1++ = orderT;
      isC[orderV]++;
    } else {
    }
  }*/
  ptr0 = orderL + (2 * t2o[timeD + 1]);  //注意
  REP(i, o0) {                           //時間情報が保持されていない
    int orderV = *ptr0++;
    int orderT = *ptr0++;
    if (1) {
      if (isC[orderV] == 0) {
        *ptr1++ = orderV;
        *ptr1++ = orderT;
      }
      isC[orderV]++;
    } else {  //次で配達すべき
    }
  }
  numCV = 0;
  REP(i, N) numCV += isC[i] > 0;
  // PRINTARR(orderC, orderC + (ptr1 - orderC));
  // DUMP(o0, numCV, (ptr1 - orderC) / 2);

  return;
}
//入力　今回配達する箇所及び0
//出力　numGクラスター クラスター0には0が含まれる。0,1,2,...,numG-1の順番で配達するつもり idG,idO
void assignCluster() {
  // numCV = 32;

  if (isEndZero) {
    numCV++;
  }

  int baseNumS = 15;  //一つのクラスタ最大サイズ固定
                      // 30 14
  numG = (numCV + baseNumS - 1) / baseNumS;
  int tmp0 = numCV / numG;
  int tmp1 = numCV % numG;
  //  idG
  if (isEndZero) {
    REP(i, numCV - 1) { idG[i] = orderC[2 * i]; }
    idG[numCV - 1] = 0;
    //    DUMP(isEndZero, idG[0], orderC[0], numCV);
  } else {
    REP(i, numCV) { idG[i] = orderC[2 * i]; }
  }
  REP(i, numG) { idO[i + 1] = idO[i] + tmp0 + (i < tmp1); }
  //  assert(idO[numG] == numCV);
  // DUMP(numCV, numG, tmp0, tmp1);

  //  PRINTARR(idG, idG + numCV);
  // REP(i, ) { orderC[] }
  // orderCを元にクラスタ作成
  //クラスタに必要な情報　id,nextid, offset0, offset1, numE,sumT,各頂点の到着時刻

  return;
}
//入力 firstDG,pathAllG,pathNG
//出力　答え
inline void outPath() {
  REP(i, firstDG) cout << "-1\n";
  int time = firstDG;
  int start = pathAllG[0];
  REPS(i, pathNG - 1) {
    int goal = pathAllG[i];
    int remain = Tmax - time;
    int prev = start;
    int cur = Pnext[start][goal];
    int len = d[start][goal];
    //    DUMP(Tmax, time);
    if (len > remain) {
      if (remain == 0) return;
      while (1) {
        REP(j, d[prev][cur]) {
          cout << cur + 1 << "\n";
          remain--;
          if (remain == 0) return;
        }
        prev = cur;
        cur = Pnext[cur][goal];
      }
    } else {
      while (1) {
        REP(j, d[prev][cur]) cout << cur + 1 << "\n";
        if (cur == goal) break;
        prev = cur;
        cur = Pnext[cur][goal];
      }
    }
    time += len;
    start = pathAllG[i];
  }
  FOR(j, time, Tmax) cout << "-1\n";
  return;
}

Measured memory_bytes: 8192