Problem: There are n players numbered from 0 to n-1 with ranks. The i-th player has rank i.

Players can form teams: the team should consist of three players and no pair of players in the team should have a conflict. The rank of the team is calculated using the following algorithm: let i, j, k be the ranks of players in the team and i < j < k, then the rank of the team is equal to A ⋅ i + B ⋅ j + C ⋅ k.

You are given information about the pairs of players who have a conflict. Calculate the total sum of ranks over all possible valid teams modulo 2^{64}.

Input

The first line contains two space-separated integers n and m (3 ≤ n ≤ 2 ⋅ 10^5, 0 ≤ m ≤ 2 ⋅ 10^5) — the number of players and the number of conflicting pairs.

The second line contains three space-separated integers A, B and C (1 ≤ A, B, C ≤ 10^6) — coefficients for team rank calculation.

Each of the next m lines contains two space-separated integers u_i and v_i (0 ≤ u_i, v_i < n, u_i ≠ v_i) — pair of conflicting players.

It's guaranteed that each unordered pair of players appears in the input file no more than once.

Output

Print single integer — the total sum of ranks over all possible teams modulo 2^{64}.

Examples

Input

4 0
2 3 4


Output

64


Input

4 1
2 3 4
1 0


Output

38


Input

6 4
1 5 3
0 3
3 5
5 4
4 3


Output

164

Note

In the first example all 4 teams are valid, i.e. triples: {0, 1, 2}, {0, 1, 3}, {0, 2, 3} {1, 2, 3}.

In the second example teams are following: {0, 2, 3}, {1, 2, 3}.

In the third example teams are following: {0, 1, 2}, {0, 1, 4}, {0, 1, 5}, {0, 2, 4}, {0, 2, 5}, {1, 2, 3}, {1, 2, 4}, {1, 2, 5}.

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline bool cmax(T& x, T y) {
  return y > x ? x = y, true : false;
}
template <typename T>
inline bool cmin(T& x, T y) {
  return y < x ? x = y, true : false;
}
template <typename T>
inline T dmax(T x, T y) {
  return x > y ? x : y;
}
template <typename T>
inline T dmin(T x, T y) {
  return x < y ? x : y;
}
const int MAXN = 2e5 + 5;
const int oo = 0x3f3f3f3f;
namespace Hash {
const int mod = 2333333;
const int step = 1717171;
inline int add(int a, int b) {
  a += b;
  return a >= mod ? a - mod : a;
}
inline int pop(int a, int b) {
  a -= b;
  return a < 0 ? a + mod : a;
}
inline int mul(int a, int b) { return (long long)a * b % mod; }
struct edge {
  pair<int, int> w;
  int next;
} e[MAXN << 1];
int LINK[mod], len;
inline void ins(int x, pair<int, int> w) {
  e[++len].next = LINK[x];
  LINK[x] = len;
  e[len].w = w;
}
bool get(pair<int, int> w) {
  int x = add(mul(w.first, step), w.second);
  for (int i = LINK[x]; i; i = e[i].next)
    if (e[i].w == w) return 1;
  return 0;
}
void ins(pair<int, int> w) {
  int x = add(mul(w.first, step), w.second);
  ins(x, w);
}
}  // namespace Hash
using Hash::get;
using Hash::ins;
int N, M, w[3], deg[MAXN];
unsigned long long ans = 0, A, B, C;
inline unsigned long long calc(long long cl, long long cr) {
  return cl <= cr ? (cl + cr) * (cr - cl + 1) / 2 : 0;
}
int ord[MAXN], cnt = 0;
vector<int> G[MAXN];
void cal(int x, int y) {
  if (1 < x) {
    ans -= calc(0, x - 2) * A;
    ans -= (x - 1) * B * (x - 1);
    ans -= (x - 1) * C * (y - 1);
  }
  if (x + 1 < y) {
    ans -= (y - x - 1) * A * (x - 1);
    ans -= calc(x, y - 2) * B;
    ans -= (y - x - 1) * C * (y - 1);
  }
  if (y < N) {
    ans -= (N - y) * A * (x - 1);
    ans -= (N - y) * B * (y - 1);
    ans -= C * calc(y, N - 1);
  }
}
int main() {
  scanf("%d%d", &N, &M);
  scanf("%llu%llu%llu", &A, &B, &C);
  for (int i = 1; i <= M; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    x++;
    y++;
    ins(make_pair(x, y));
    ins(make_pair(y, x));
    G[x].push_back(y);
    G[y].push_back(x);
    deg[x]++;
    deg[y]++;
    if (x > y) swap(x, y);
    cal(x, y);
  }
  for (int i = 0; i <= N - 3; i++) ans += A * i * calc(0, N - 1 - i - 1);
  for (int i = 1; i <= N - 2; i++) ans += B * i * i * (N - 1 - i);
  for (int i = 2; i <= N - 1; i++) ans += C * i * calc(0, i - 1);
  for (int node = 1; node <= N; node++) {
    cnt = 0;
    for (int i = 0; i <= (int)G[node].size() - 1; i++) ord[++cnt] = G[node][i];
    if (cnt <= 1) continue;
    sort(ord + 1, ord + cnt + 1);
    int mi = 0;
    while (mi + 1 <= cnt && ord[mi + 1] <= node) mi++;
    ans += B * (node - 1) * mi * (cnt - mi);
    for (int i = 1; i <= mi; i++) ans += A * (ord[i] - 1) * (cnt - mi);
    for (int i = mi + 1; i <= cnt; i++) ans += C * (ord[i] - 1) * mi;
    ans += A * (node - 1) * calc(0, cnt - mi - 1);
    for (int i = mi + 1; i <= cnt; i++) ans += B * (ord[i] - 1) * (cnt - i);
    for (int i = mi + 2; i <= cnt; i++) ans += C * (ord[i] - 1) * (i - mi - 1);
    ans += C * (node - 1) * calc(0, mi - 1);
    for (int i = 1; i <= mi; i++) ans += B * (ord[i] - 1) * (i - 1);
    for (int i = 1; i <= mi; i++) ans += A * (ord[i] - 1) * (mi - i);
  }
  int lim = sqrt(M);
  cnt = 0;
  for (int node = 1; node <= N; node++)
    if (deg[node] <= lim) {
      int n = (int)G[node].size() - 1;
      for (int i = 0; i <= n; i++) {
        if (deg[G[node][i]] <= lim && G[node][i] < node) continue;
        for (int j = i + 1; j <= n; j++) {
          if (deg[G[node][j]] <= lim && G[node][j] < node) continue;
          if (!get(make_pair(G[node][i], G[node][j]))) continue;
          w[0] = node;
          w[1] = G[node][i];
          w[2] = G[node][j];
          sort(w, w + 3);
          ans -= (w[0] - 1) * A + (w[1] - 1) * B + (w[2] - 1) * C;
        }
      }
    } else
      ord[++cnt] = node;
  if (cnt >= 3) {
    sort(ord + 1, ord + cnt + 1);
    for (int i = 1; i <= cnt; i++)
      for (int j = i + 1; j <= cnt; j++)
        if (get(make_pair(ord[i], ord[j])))
          for (int k = j + 1; k <= cnt; k++)
            if (get(make_pair(ord[j], ord[k])) &&
                get(make_pair(ord[i], ord[k])))
              ans -= (ord[i] - 1) * A + (ord[j] - 1) * B + (ord[k] - 1) * C;
  }
  printf("%llu\n", ans);
  return 0;
}