#include <bits/stdc++.h>
using namespace std;
template <typename T>
void read(T &x) {
  x = 0;
  int f = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  x *= f;
}
inline void write(int x) {
  if (x < 0) x = -x, putchar('-');
  if (x > 9) write(x / 10);
  putchar(x % 10 + '0');
}
const int N = 100005, M = 300005;
int n, m, ex[M], ey[M], ez[M];
namespace work1 {
int v[M], lv;
struct Union_Find_Set {
  int fa[N], siz[N], tot, stx[N << 1], stf[N << 1], stz[N << 1], stv[N << 1],
      top;
  inline void init(int n) {
    top = 0, tot = n;
    for (int i = 1; i <= n; ++i) fa[i] = i, siz[i] = 1;
  }
  inline int Find(int x) {
    while (x ^ fa[x]) x = fa[x];
    return x;
  }
  inline int Merge(int x, int y) {
    while (x ^ fa[x]) x = fa[x];
    while (y ^ fa[y]) y = fa[y];
    if (x == y) return 0;
    if (siz[x] > siz[y]) swap(x, y);
    ++top;
    stx[top] = x, stf[top] = fa[x], stz[top] = siz[x];
    ++top;
    stx[top] = y, stf[top] = fa[y], stz[top] = siz[y];
    stv[top] = ((siz[x] & 1) && (siz[y] & 1)) ? 2 : 0;
    fa[x] = y, siz[y] += siz[x], tot -= stv[top];
    return 2;
  }
  inline void back(int s) {
    while (s--)
      fa[stx[top]] = stf[top], siz[stx[top]] = stz[top], tot += stv[top], --top;
  }
  inline bool ok() { return !tot; }
} S;
int ans[M];
vector<int> G[M];
inline void solve(int l, int r, int ql, int qr) {
  if (l > r) return;
  int i, j, id, mid = l + r >> 1, s = 0;
  for (i = l; i <= mid; ++i)
    if (ez[i] < ql) s += S.Merge(ex[i], ey[i]);
  for (i = ql; i <= qr; ++i) {
    for (j = 0; j < G[i].size(); ++j) {
      id = G[i][j];
      if (id > mid) break;
      s += S.Merge(ex[id], ey[id]);
      if (S.ok()) {
        ans[mid] = i;
        break;
      }
    }
    if (ans[mid]) break;
  }
  S.back(s), s = 0;
  if (!ans[mid]) {
    for (i = l; i <= mid; ++i)
      if (ez[i] <= ql) s += S.Merge(ex[i], ey[i]);
    solve(mid + 1, r, ql, qr);
    S.back(s);
    return;
  }
  for (i = ql; i < ans[mid]; ++i)
    for (j = 0; j < G[i].size(); ++j)
      if ((id = G[i][j]) < l)
        s += S.Merge(ex[id], ey[id]);
      else
        break;
  solve(l, mid - 1, ans[mid], qr);
  S.back(s);
  s = 0;
  for (i = l; i <= mid; ++i)
    if (ez[i] < ql) s += S.Merge(ex[i], ey[i]);
  solve(mid + 1, r, ql, ans[mid]);
  S.back(s);
}
inline void MAIN() {
  int i;
  S.init(n);
  for (i = 1; i <= m; ++i) v[i] = ez[i];
  sort(v + 1, v + m + 1), lv = unique(v + 1, v + m + 1) - v - 1;
  for (i = 1; i <= m; ++i)
    ez[i] = lower_bound(v + 1, v + lv + 1, ez[i]) - v, G[ez[i]].push_back(i);
  solve(1, m, 1, lv);
  for (i = 1; i <= m; ++i) ans[i] = ans[i] ? v[ans[i]] : -1;
  for (i = 1; i <= m; ++i) write(ans[i]), putchar('\n');
}
}  // namespace work1
int main() {
  int i;
  read(n), read(m);
  for (i = 1; i <= m; ++i) read(ex[i]), read(ey[i]), read(ez[i]);
  work1::MAIN();
  return 0;
}
