#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <set>
using namespace std;

const int MAXN = 100005;

vector<int> graph[MAXN];
bool visited[MAXN];
int discoveryTime[MAXN], low[MAXN];
int timer = 0;
vector<pair<int, int>> bridges;

// Hàm DFS tìm cầu
void findBridges(int u, int parent) {
    visited[u] = true;
    discoveryTime[u] = low[u] = ++timer;

    for (int v : graph[u]) {
        if (v == parent) continue; // Bỏ qua cạnh quay về cha
        if (!visited[v]) {
            findBridges(v, u);
            low[u] = min(low[u], low[v]);

            // Kiểm tra nếu (u, v) là cầu
            if (low[v] > discoveryTime[u]) {
                bridges.emplace_back(u, v);
            }
        } else {
            low[u] = min(low[u], discoveryTime[v]);
        }
    }
}

// Hàm DFS để đếm số đỉnh trong một thành phần liên thông
int countComponentSize(int u, vector<bool>& visited) {
    visited[u] = true;
    int size = 1;
    for (int v : graph[u]) {
        if (!visited[v]) {
            size += countComponentSize(v, visited);
        }
    }
    return size;
}

int main() {
    int N, M;
    cin >> N >> M;

    // Đọc đồ thị
    vector<pair<int, int>> edges;
    for (int i = 0; i < M; ++i) {
        int u, v;
        cin >> u >> v;
        graph[u].push_back(v);
        graph[v].push_back(u);
        edges.emplace_back(u, v); // Lưu danh sách các cạnh
    }

    // Tìm các cầu trong đồ thị
    memset(visited, false, sizeof(visited));
    for (int i = 1; i <= N; ++i) {
        if (!visited[i]) {
            findBridges(i, -1);
        }
    }

    // Lưu danh sách các cầu để kiểm tra nhanh
    set<pair<int, int>> bridgeSet;
    for (auto [u, v] : bridges) {
        bridgeSet.insert({u, v});
        bridgeSet.insert({v, u}); // Lưu cả hai chiều để kiểm tra nhanh
    }

    // Xử lý từng cạnh
    for (auto [u, v] : edges) {
        // Nếu không phải cầu, in 0
        if (bridgeSet.find({u, v}) == bridgeSet.end()) {
            cout << 0 << endl;
            continue;
        }
        
        // Loại bỏ cầu khỏi đồ thị
        graph[u].erase(remove(graph[u].begin(), graph[u].end(), v), graph[u].end());
        graph[v].erase(remove(graph[v].begin(), graph[v].end(), u), graph[v].end());

        // Nếu là cầu, tính số cặp không kết nối
        vector<bool> tempVisited(N + 1, false);

        // Đếm số đỉnh trong thành phần chứa u
        int sizeU = countComponentSize(u, tempVisited);

        // Thành phần chứa v có kích thước là phần còn lại
        int sizeV = N - sizeU;

        // Tính số cặp không kết nối
        cout << sizeU * sizeV << endl;
        
        // Khôi phục cầu vào đồ thị
        graph[u].push_back(v);
        graph[v].push_back(u);
    }

    return 0;
}
