#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;
 
typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define F0R(i, a) for (int i=0; i<(a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)

#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()

const int MOD = 1000000007;
const ll INF = 1e18;
const int MX = 100001;

int N,M;
int nor, bip, sing, done[MX];
ll ans;
vi adj[MX];
bool ok = 1;

ll sq(ll x) { return x*x; };

void dfs(int x, int y) {
    if (done[x]) {
        if (done[x] != y) ok = 0;
        return;
    }
    // cout << "HUH " << x << "\n";
    done[x] = y;
    for (int i: adj[x]) dfs(i,y^3);
}

void solve(int x) {
    if (sz(adj[x]) == 0) {
        sing ++;
        return;
    }
    ok = 1;
    dfs(x,1); // cout << "OOPS " << x << "\n";
    if (ok) bip ++;
    else nor ++;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0);
    cin >> N >> M;
    F0R(i,M) {
        int u,v; cin >> u >> v;
        adj[u].pb(v), adj[v].pb(u);
    }
    FOR(i,1,N+1) if (!done[i]) {
        //cout << i << "\n";
        solve(i);
    }
    //cout << nor << " " << bip << " " << sing << "\n";
    F0R(i,sing) {
        ans += 2*N-1; N --;
    }
    //cout << ans << "\n";
    ans += sq(bip);
    ans += sq(nor+bip);
    cout << ans;
}

// read the question correctly (is y a vowel? what are the exact constraints?)
// look out for SPECIAL CASES (n=1?) and overflow (ll vs int?) ARRAY OUT OF BOUNDSS
/*
これを入れて実行
g++ code.cpp
./a.out
 */
 
#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
#include <cstring>
#include <queue>
#include <deque>
#include <stack>
#include <algorithm>
#include <utility>
#include <set>
#include <map>
#include <unordered_map>
#include <cmath>
#include <math.h>
#include <tuple>
#include <iomanip>
#include <bitset>
#include <functional>
#include <cassert>

#define all(x) (x).begin(),(x).end()
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
 
using namespace std;
typedef long long ll;
typedef long double ld;
 
int dy4[4] = {-1, 0, +1, 0};
int dx4[4] = {0, +1, 0, -1};
int dy8[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
int dx8[8] = {0, 1, 1, 1, 0, -1, -1, -1};
 
const long long INF = 1LL << 60;
const ll MOD = 1e9 + 7;
 
bool greaterSecond(const pair<int, int>& f, const pair<int, int>& s){
    return f.second > s.second;
}
 
ll gcd(ll a, ll b){
	if (b == 0)return a;
	return gcd(b, a % b);
}
 
ll lcm(ll a, ll b){
    return a / gcd(a, b) * b;
}

ll conbinationMemo[100][100];

void cmemoInit(){
    rep(i, 100){
        rep(j, 100){
            conbinationMemo[i][j] = -1;
        }
    }
}
 
ll nCr(ll n, ll r){
    if(conbinationMemo[n][r] != -1) return conbinationMemo[n][r];
    if(r == 0 || r == n){
        return 1;
    } else if(r == 1){
        return n;
    }
    return conbinationMemo[n][r] = (nCr(n - 1, r) + nCr(n - 1, r - 1));
}
 
ll nPr(ll n, ll r){
    r = n - r;
    ll ret = 1;
    for (ll i = n; i >= r + 1; i--) ret *= i;
    return ret;
}
//-----------------------ここから-----------
ll n, m;
vector<vector<ll>> g;
vector<vector<ll>> rg;
vector<ll> t;
void dfs(ll now, vector<int> &visited){
    visited[now] = 1;
    rep(i, g[now].size()){
        ll next = g[now][i];
        if(visited[next]) continue;
        dfs(next, visited);
    }
    t.push_back(now);
}
int main(void){

    cin >> n >> m;
    g.resize(n);
    rg.resize(n);
    vector<int> appeared(n, 0);
    rep(i, n - 1 + m){
        ll a, b;
        cin >> a >> b;
        a--, b--;
        g[a].push_back(b);
        rg[b].push_back(a);
        appeared[b] = 1;
    }
    ll root = 0;
    rep(i, n){
        if(!appeared[i]){
            root = i;
            break;
        }
    }

    vector<int> visited(n, 0);
    dfs(root, visited);

    reverse(all(t));

    map<ll,ll> mp;
    rep(i, t.size()){
        mp[t[i]] = i;
    }

    rep(i, n){
        sort(all(rg[i]), [&mp](const ll &f, const ll &s){
            return mp[f] > mp[s];
        });
    }
    vector<ll> ans(n);
    rep(i, n){
        if(rg[i].size() == 0){
            ans[i] = 0;
        } else {
            ans[i] = rg[i][0] + 1;
        }
    }

    rep(i, ans.size()){
        cout << ans[i] << endl;
    }

    
}
