You are given an undirected graph G. G has N vertices and M edges. The vertices are numbered from 1 through N, and the i-th edge (1 ≤ i ≤ M) connects Vertex a_i and b_i. G does not have self-loops and multiple edges.

You can repeatedly perform the operation of adding an edge between two vertices. However, G must not have self-loops or multiple edges as the result. Also, if Vertex 1 and 2 are connected directly or indirectly by edges, your body will be exposed to a voltage of 1000000007 volts. This must also be avoided.

Under these conditions, at most how many edges can you add? Note that Vertex 1 and 2 are never connected directly or indirectly in the beginning.

Constraints

* 2 ≤ N ≤ 10^5
* 0 ≤ M ≤ 10^5
* 1 ≤ a_i < b_i ≤ N
* All pairs (a_i, b_i) are distinct.
* Vertex 1 and 2 in G are not connected directly or indirectly by edges.

Input

Input is given from Standard Input in the following format:


N M
a_1 b_1
:
a_M b_M


Output

Print the maximum number of edges that can be added.

Examples

Input

4 1
1 3


Output

2


Input

2 0


Output

0


Input

9 6
1 4
1 8
2 5
3 6
4 8
5 7


Output

12
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
#define rep(i, n) for(int i = 0; i < n; i++)
#define pb push_back
vector<vector<int>> graph(101010);
int memo[101010];

// グラフを幅優先探索する.
// https://ja.wikipedia.org/wiki/幅優先探索
// ※bfsの動作確認用.
// @param s: 探索開始の頂点番号.
// @param l: 連結成分番号.
// @return: 特に無し.
void bfs(int s, int l){
    
    // 1. 空のキュー.
    queue<int> q;
    
    // 2. 訪問済みフラグ設定.
    memo[s] = l;
    
    // 3. 探索地点 s をキュー q に追加.
    q.push(s);
    
    // 4. キュー q が 空になるまで, 探索.
    while(!q.empty()) {
        
        // 5. 頂点 u を キュー q から取り出す.
        int u = q.front();
        q.pop();
        
        // 6. 取り出した要素を処理.
        for(auto &e : graph[u]){
            // 7. 頂点u の 隣接する頂点e が, 未訪問だったら, キュー q に追加.
            if(memo[e] == 0 && e != s){
                // 頂点e を キュー q に追加.
                q.push(e);
                // 頂点e を 訪問済みに設定.
                memo[e] = l;
            }
        }
    }
}

int main(){
    
    // 1. 入力情報.
    int N, M;
    scanf("%d %d", &N, &M);
    rep(i, M){
        int a, b;
        scanf("%d %d", &a, &b);
        a--, b--;
        graph[a].pb(b);
        graph[b].pb(a);
    }
    
    // 2. グラフを連結成分に分割.
    int l = 1;
    rep(i, N) if(memo[i] == 0) bfs(i, l), l++;
    // rep(i, N) printf("%d ", memo[i]);
    // puts("");
    
    // 3. 連結成分の情報を整理.
    // 3-1. 頂点1, 2, それ以外の頂点について, 連結している頂点数を確認.
    LL one = 0, two = 0, other = 0;
    rep(i, N){
        if(memo[i] == 1) one++;
        if(memo[i] == 2) two++;
        if(memo[i] >= 3) other++;
    }
    
    // 3-2. 頂点1, 2 の中で, 連結している頂点数が多い方に, 
    // 残りの頂点をマージ.
    if(one >= two) one += other;
    else           two += other;
    
    // 4. 最大で何本の辺を付け足せるか？
    // ※ int -> LL に 修正.
    LL ans = 0;
    ans += one * (one - 1) / 2;
    ans += two * (two - 1) / 2;
    ans -= M;
    
    // 5. 出力.
    printf("%lld\n", ans);
    return 0;
    
}