def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]
# 同一の集合の判定
def same(x, y):
    if find(x) == find(y):
        return True
    else:
        return False
# 集合の併合
def unite(x, y):
    x = find(x)
    y = find(y)
    if x == y:
        return
    if par[x] > par[y]:
        x, y = y, x
    par[x] += par[y]
    par[y] = x

# 集合の数
def uCnt(x):
    return -par[find(x)]

N, M = map(int, input().split())
par = [-1 for i in range(N)]
tmp = ((N * (N - 1)) // 2)
ab = [list(map(int, input().split())) for _ in range(M)]
ans = [0] * M
ans[M - 1] = tmp
for i in range(M - 1, 0, -1):
    fa = find(ab[i][0] - 1)
    fb = find(ab[i][1] - 1)
    ans[i - 1] = ans[i]
    if fa != fb:
        ans[i - 1] -= uCnt(fa) * uCnt(fb)
        unite(ab[i][0] - 1, ab[i][1] - 1)

for i in ans:
    print(i) def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]
# 同一の集合の判定 find if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]
# 同一の集合の判定 par[x] < 0 par[x] par x 0 return x x par[x] = find(par[x]) par[x] par x find(par[x]) find par[x] par x return par[x] par[x] par x x x def same(x, y):
    if find(x) == find(y):
        return True
    else:
        return False
# 集合の併合 same if find(x) == find(y):
        return True
    else:
        return False
# 集合の併合 find(x) == find(y) find(x) find x find(y) find y return True True return False False x x y y def unite(x, y):
    x = find(x)
    y = find(y)
    if x == y:
        return
    if par[x] > par[y]:
        x, y = y, x
    par[x] += par[y]
    par[y] = x

# 集合の数 unite x = find(x) x find(x) find x y = find(y) y find(y) find y if x == y:
        return
     x == y x y return if par[x] > par[y]:
        x, y = y, x
     par[x] > par[y] par[x] par x par[y] par y x, y = y, x x y y x par[x] += par[y] par[x] par x par[y] par y par[y] = x par[y] par y x x x y y def uCnt(x):
    return -par[find(x)] uCnt return -par[find(x)] -par[find(x)] par[find(x)] par find(x) find x x x N, M = map(int, input().split()) N map(int, input().split()) map int input().split() ().split () input split M -1 for i in range(N) for i in range(N) i range(N) range N for i in range(N) -1 par = [-1 for i in range(N)] par [-1 for i in range(N)] tmp = ((N * (N - 1)) // 2) tmp (N * (N - 1)) // 2 N * (N - 1) N N - 1 N 1 2 list(map(int, input().split())) for _ in range(M) for _ in range(M) _ range(M) range M for _ in range(M) list(map(int, input().split())) list map(int, input().split()) map int input().split() ().split () input split ab = [list(map(int, input().split())) for _ in range(M)] ab [list(map(int, input().split())) for _ in range(M)] ans = [0] * M ans [0] * M [0] 0 M ans[M - 1] = tmp ans[M - 1] ans M - 1 M 1 tmp for i in range(M - 1, 0, -1):
    fa = find(ab[i][0] - 1)
    fb = find(ab[i][1] - 1)
    ans[i - 1] = ans[i]
    if fa != fb:
        ans[i - 1] -= uCnt(fa) * uCnt(fb)
        unite(ab[i][0] - 1, ab[i][1] - 1) i range(M - 1, 0, -1) range M - 1 M 1 0 -1 fa = find(ab[i][0] - 1) fa find(ab[i][0] - 1) find ab[i][0] - 1 ab[i][0] [i] ab i 0 1 fb = find(ab[i][1] - 1) fb find(ab[i][1] - 1) find ab[i][1] - 1 ab[i][1] [i] ab i 1 1 ans[i - 1] = ans[i] ans[i - 1] ans i - 1 i 1 ans[i] ans i if fa != fb:
        ans[i - 1] -= uCnt(fa) * uCnt(fb)
        unite(ab[i][0] - 1, ab[i][1] - 1) fa != fb fa fb ans[i - 1] -= uCnt(fa) * uCnt(fb) ans[i - 1] ans i - 1 i 1 uCnt(fa) * uCnt(fb) uCnt(fa) uCnt fa uCnt(fb) uCnt fb unite(ab[i][0] - 1, ab[i][1] - 1) unite ab[i][0] - 1 ab[i][0] [i] ab i 0 1 ab[i][1] - 1 ab[i][1] [i] ab i 1 1 for i in ans:
    print(i) i ans print(i) print i ab = [list(map(int, input().split())) for _ in range(M)] [list(map(int, input().split())) for _ in range(M)] ab def unite(x, y):
    x = find(x)
    y = find(y)
    if x == y:
        return
    if par[x] > par[y]:
        x, y = y, x
    par[x] += par[y]
    par[y] = x

# 集合の数 def unite(x, y):
    x = find(x)
    y = find(y)
    if x == y:
        return
    if par[x] > par[y]:
        x, y = y, x
    par[x] += par[y]
    par[y] = x

# 集合の数 unite ans = [0] * M [0] * M ans def uCnt(x):
    return -par[find(x)] def uCnt(x):
    return -par[find(x)] uCnt N, M = map(int, input().split()) map(int, input().split()) N def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]
# 同一の集合の判定 def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]
# 同一の集合の判定 find par = [-1 for i in range(N)] [-1 for i in range(N)] par tmp = ((N * (N - 1)) // 2) (N * (N - 1)) // 2 tmp fa = find(ab[i][0] - 1) find(ab[i][0] - 1) fa fb = find(ab[i][1] - 1) find(ab[i][1] - 1) fb def same(x, y):
    if find(x) == find(y):
        return True
    else:
        return False
# 集合の併合 def same(x, y):
    if find(x) == find(y):
        return True
    else:
        return False
# 集合の併合 same M = map(int, input().split()) map(int, input().split()) M
def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]
# 同一の集合の判定
def same(x, y):
    if find(x) == find(y):
        return True
    else:
        return False
# 集合の併合
def unite(x, y):
    x = find(x)
    y = find(y)
    if x == y:
        return
    if par[x] > par[y]:
        x, y = y, x
    par[x] += par[y]
    par[y] = x

# 集合の数
def uCnt(x):
    return -par[find(x)]

N, M = map(int, input().split())
par = [-1 for i in range(N)]
tmp = ((N * (N - 1)) // 2)
ab = [list(map(int, input().split())) for _ in range(M)]
ans = [0] * M
ans[M - 1] = tmp
for i in range(M - 1, 0, -1):
    fa = find(ab[i][0] - 1)
    fb = find(ab[i][1] - 1)
    ans[i - 1] = ans[i]
    if fa != fb:
        ans[i - 1] -= uCnt(fa) * uCnt(fb)
        unite(ab[i][0] - 1, ab[i][1] - 1)

for i in ans:
    print(i)