Problem:
Score : 1400 points

Problem Statement

There are N turkeys.
We number them from 1 through N.

M men will visit here one by one.
The i-th man to visit will take the following action:

If both turkeys x_i and y_i are alive: selects one of them with equal probability, then eats it.

If either turkey x_i or y_i is alive (but not both): eats the alive one.

If neither turkey x_i nor y_i is alive: does nothing.

Find the number of pairs (i,\ j) (1 ≤ i < j ≤ N) such that the following condition is held:

The probability of both turkeys i and j being alive after all the men took actions, is greater than 0.

Constraints

2 ≤ N ≤ 400

1 ≤ M ≤ 10^5

1 ≤ x_i < y_i ≤ N

Input

Input is given from Standard Input in the following format:

N M
x_1 y_1
x_2 y_2
:
x_M y_M

Output

Print the number of pairs (i,\ j) (1 ≤ i < j ≤ N) such that the condition is held.

Sample Input 1

3 1
1 2

Sample Output 1

2

(i,\ j) = (1,\ 3), (2,\ 3) satisfy the condition.

Sample Input 2

4 3
1 2
3 4
2 3

Sample Output 2

1

(i,\ j) = (1,\ 4) satisfies the condition.
Both turkeys 1 and 4 are alive if:

The first man eats turkey 2.

The second man eats turkey 3.

The third man does nothing.

Sample Input 3

3 2
1 2
1 2

Sample Output 3

0

Sample Input 4

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

Sample Output 4

5

Solution in C++14 (GCC 5.4.1) (judge verdict: Runtime Error)

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

const int MAX_N = 405;

vector<pair<int, int>> adj [MAX_N];

int vis [MAX_N];
int fuck [MAX_N];
vector<pair<int, pair<int, int>>> constr [MAX_N];

void add_constr (int u, int t, int src) {
  vis[u] = 1;
  for (pair<int, int> nxt : adj[u]) {
    if (nxt.first >= t) {
      break;
    }

    if (vis[nxt.first]) {
      fuck[src] = 1;
      break;
    }

    constr[src].push_back(make_pair(nxt.first, make_pair(u, nxt.second)));
    add_constr(nxt.second, nxt.first, src);
  }
}

vector<pair<int, pair<int, int>>> merge (const vector<pair<int, pair<int, int>>> &u,
                                         const vector<pair<int, pair<int, int>>> &v) {
  vector<pair<int, pair<int, int>>> ans;
  int uptr = 0, vptr = 0;
  while (uptr < (int) u.size() && vptr < (int) v.size()) {
    if (u[uptr] < v[vptr]) {
      ans.push_back(u[uptr]);
      uptr++;
    } else {
      ans.push_back(v[vptr]);
      vptr++;
    }
  }

  while (uptr < (int) u.size()) {
    ans.push_back(u[uptr]);
    uptr++;
  }

  while (vptr < (int) v.size()) {
    ans.push_back(v[vptr]);
    vptr++;
  }

  return ans;
}

int indeg [MAX_N];
bool fits (int u, int v, int n) {
  for (int i = 1; i <= n; i++) {
    indeg[i] = 0;
  }

  vector<pair<int, pair<int, int>>> merged = merge(constr[u], constr[v]);
  pair<int, pair<int, int>> last = {-1, {-1, -1}};
  for (auto pr : merged) {
    if (pr.first == last.first) {
      if (pr.second != last.second) {
        return false;
      }
    } else {
      indeg[pr.second.second]++;
    }
    last = pr;
  }

  for (int i = 1; i <= n; i++) {
    if (indeg[i] > 1) return false;
  }

  if (indeg[u] > 0) return false;
  if (indeg[v] > 0) return false;
  return true;
}

int main () {
  ios::sync_with_stdio(false);

  int n, m;
  cin >> n >> m;

  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;

    adj[u].push_back(make_pair(i, v));
    adj[v].push_back(make_pair(i, u));
  }

  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      vis[j] = 0;
    }
    add_constr(i, m, i);
    sort(constr[i].begin(), constr[i].end());
  }

  int ans = 0;
  for (int u = 1; u <= n; u++) {
    if (!fuck[u]) {
      for (int v = u + 1; v <= n; v++) {
        if (!fuck[v]) {
          if (fits(u, v, n)) {
            ans++;
          }
        }
      }
    }
  }

  cout << ans << endl;
}