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
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<n;i++)
#define cinf(n,x) for(int i=0;i<(n);i++)cin>>x[i];
#define ft first
#define sc second
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define all(v) (v).begin(),(v).end()
#define mod 1000000007
using namespace std;
typedef long long ll;
template<class T> using V=vector<T>;
using Graph = vector<vector<int>>;
using P=pair<ll,ll>;
typedef unsigned long long ull;
typedef long double ldouble;
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }

const ll INF=1e18;

class UnionFind{
public:
	vector<ll> par,num;
 
	ll find(ll v){
		return (par[v]==v)? v: (par[v]=find(par[v]));
	}
	explicit UnionFind(ll N):par(N),num(N,1){
		iota(par.begin(),par.end(),0);
	}
	void unite(ll u,ll v){
		u=find(u),v=find(v);
		if(u==v)return ;
		if(num[u]<num[v])swap(u,v);
		num[u] += num[v];
		par[v] = u;
	}
	bool same(ll u,ll v){
		return find(u) == find(v);
	}
	bool ispar(ll v){
		return v=find(v);
	}
	ll size(ll v){
		return num[find(v)];
	}
};

int main(){
    ll n,m;
    cin>>n>>m;
    UnionFind G(n);
    V<ll> a(m),b(m);
    rep(i,m){
        cin>>a[i]>>b[i];
        a[i]--;b[i]--;
        G.unite(a[i],b[i]);
    }
    V<ll> e(3,0);
    rep(i,m){
        if(G.same(0,a[i])||G.same(0,b[i])) e[0]++;
        else if(G.same(1,a[i])||G.same(1,b[i])) e[1]++;
        else e[2]++;
    }
    ll ans=0;
    V<ll> v(3);
    rep(i,2) v[i]=G.size(i);
    v[2]=n-v[0]-v[1];
    ll v_max;
    if(v[0]>v[1]) v_max=0;
    else v_max=1;
    ll v_min=v_max^1;
    ans+=v[v_min]*(v[v_min]-1)/2-e[v_min];
    ll u=v[v_max]+v[2];
    ans+=u*(u-1)/2-e[v_max]-e[2];
    cout<<ans<<endl;
}
//ペナルティ出しても焦らない　ACできると信じろ！！！
/*
V,P(大文字)使用不可
乗算などの際にオーバーフローに注意せよ！
(適切にmodをとれ　にぶたんで途中で切り上げろ)
制約をよく読め！
(全探索できるなら全探索しろ)
stringの計算量(扱い)注意
コーナー注意！(特に数値が小さいものについては要検証)
N行出力のときは'\n'
*/