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 <iostream>
#include <vector>
#include <algorithm>
#include <string.h>
#include <iomanip>
#include <math.h>
#include <string>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <functional>

using namespace std;

typedef long long int ll;
typedef std::pair<int, int> pii;
typedef std::pair<ll, int> pli;
typedef std::pair<ll, ll> pll;

#define FOR(i,n,m) for(ll i=(ll)(m);i<(ll)(n);++i)
#define REP(i,n) FOR(i,n,0)
#define IREP(i,n) for(ll i=(ll)(n);i>=0;--i)
#define OF64 std::setprecision(10)

const ll MOD = 1000000007;
const ll INF = (ll)1e15;

vector< vector<pii> > node;

class UnionFind
{
public:
	UnionFind() {};
	void init(int n)
	{
		max = n;
		par.resize(max);
		rank.resize(max);
		for (int i = 0; i < max; ++i)
		{
			par[i] = i;
			rank[i] = 0;
		}
	}
	int find(int x)
	{
		if (par[x] == x)return x;
		return par[x] = find(par[x]);
	}
	bool same(int x, int y)
	{
		return find(x) == find(y);
	}
	void unit(int x, int y)
	{
		x = find(x);
		y = find(y);
		if (x == y)return;

		if (rank[x] < rank[y])
		{
			par[x] = y;
		}
		else
		{
			par[y] = x;
			if (rank[x] == rank[y])
			{
				rank[x]++;
			}
		}
	}

private:
	std::vector<int> par;
	std::vector<int> rank;
	int max;
};

bool use[100005];
bool useNode[100005];

ll nodeNum(int n)
{
	ll vNum = 0;
	ll nNum = 0;
	stack<int> s;
	s.push(n);
	vNum++;
	while (!s.empty())
	{
		int m = s.top();
		s.pop();
		REP(i, node[m].size())
		{
			if (useNode[node[m][i].second])continue;
			nNum++;
			useNode[node[m][i].second] = true;
			if (use[node[m][i].first])continue;
			vNum++;
			use[node[m][i].first] = true;
			s.push(node[m][i].first);
		}
	}
	return vNum*(vNum -1) / 2 - nNum;
}

int main()
{
	int N, M;
	cin >> N >> M;
	UnionFind uf;
	uf.init(N);
	node.resize(N);
	REP(i, M)
	{
		int a, b;
		cin >> a >> b;
		a--; b--;
		node[a].push_back(pii(b,i));
		node[b].push_back(pii(a,i));
		uf.unit(a, b);
	}

	//! 存在する連結グラフを完全グラフにするような
	//! 辺を追加する
	ll ans = 0;
	//! n頂点完全グラフの辺の数はn(n+1)/2。
	//! 各グラフの辺の数を数えて、足りない分を足す
	REP(i, N)
	{
		if (use[i])continue;
		ans += nodeNum(i);
	}

	//! unionFindの親の数から、それぞれのグラフに
	//! 含まれているノードの数を調べる
	int oParent = -1;
	int tParent = -1;
	vector<int> p(N, 0);
	REP(i, N)
	{
		int n = uf.find(i);
		if (i == 0)oParent = n;
		if (i == 1)tParent = n;
		p[n]++;
	}

	//! node0,node1につながっていないグラフから、
	//! node0 or node1のグラフの各点に辺を張る
	ll m = std::max(p[oParent], p[tParent]);
	REP(i, N)
	{
		if (i == oParent || i == tParent)continue;
		ans += m*p[i];
		m += p[i];
	}

	cout << ans << endl;
	return 0;
}