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;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXN = 200000;
const int MAXM = 200000;
int n, m;
unsigned long long A, B, C;
vector<int> adj[MAXN];
int ntrilo[MAXN], ntrimi[MAXN], ntrihi[MAXN];
vector<int> adj2[MAXN];
bool exists(int a, int b) {
  int idx = lower_bound(adj[a].begin(), adj[a].end(), b) - adj[a].begin();
  return idx < ((int)(adj[a]).size()) && adj[a][idx] == b;
}
void counttriangles() {
  for (int i = (0); i < (n); ++i)
    adj2[i].clear(), ntrilo[i] = ntrimi[i] = ntrihi[i] = 0;
  for (int i = (0); i < (n); ++i)
    for (int j = (0); j < (((int)(adj[i]).size())); ++j) {
      int k = adj[i][j];
      if (((int)(adj[i]).size()) < ((int)(adj[k]).size()) ||
          ((int)(adj[i]).size()) == ((int)(adj[k]).size()) && i < k)
        adj2[i].push_back(k);
    }
  for (int i = (0); i < (n); ++i)
    for (int j = (0); j < (((int)(adj2[i]).size())); ++j)
      for (int k = (j + 1); k < (((int)(adj2[i]).size())); ++k) {
        int x = i, y = adj2[i][j], z = adj2[i][k];
        if (!exists(y, z)) continue;
        if (x < y && y < z) {
          ++ntrilo[x], ++ntrimi[y], ++ntrihi[z];
        } else if (x < z && z < y) {
          ++ntrilo[x], ++ntrimi[z], ++ntrihi[y];
        } else if (y < x && x < z) {
          ++ntrilo[y], ++ntrimi[x], ++ntrihi[z];
        } else if (y < z && z < x) {
          ++ntrilo[y], ++ntrimi[z], ++ntrihi[x];
        } else if (z < x && x < y) {
          ++ntrilo[z], ++ntrimi[x], ++ntrihi[y];
        } else if (z < y && y < x) {
          ++ntrilo[z], ++ntrimi[y], ++ntrihi[x];
        }
      }
}
unsigned long long solve() {
  for (int i = (0); i < (n); ++i) sort(adj[i].begin(), adj[i].end());
  unsigned long long ret = 0;
  for (int i = (0); i < (n); ++i) {
    int nlarger = n - i - 1, nsmaller = i;
    unsigned long long na = (long long)nlarger * (nlarger - 1) / 2,
                       nb = (long long)nsmaller * nlarger,
                       nc = (long long)nsmaller * (nsmaller - 1) / 2;
    ret += (na * A + nb * B + nc * C) * ((unsigned long long)i);
  }
  for (int a = (0); a < (n); ++a)
    for (int i = (0); i < (((int)(adj[a]).size())); ++i) {
      int b = adj[a][i];
      if (!(a < b)) continue;
      int nlarger = n - b - 1;
      unsigned long long nc = nlarger,
                         csum = (long long)(b + 1 + n - 1) * nlarger / 2;
      ret -= nc * ((unsigned long long)a * A + (unsigned long long)b * B) +
             csum * C;
    }
  for (int b = (0); b < (n); ++b)
    for (int i = (0); i < (((int)(adj[b]).size())); ++i) {
      int c = adj[b][i];
      if (!(b < c)) continue;
      int nsmaller = b;
      unsigned long long na = nsmaller,
                         asum = (long long)(0 + b - 1) * nsmaller / 2;
      ret -= na * ((unsigned long long)b * B + (unsigned long long)c * C) +
             asum * A;
    }
  for (int a = (0); a < (n); ++a)
    for (int i = (0); i < (((int)(adj[a]).size())); ++i) {
      int c = adj[a][i];
      if (!(a < c)) continue;
      int nbetween = c - a - 1;
      unsigned long long nb = nbetween,
                         bsum = (long long)(a + 1 + c - 1) * nbetween / 2;
      ret -= nb * ((unsigned long long)a * A + (unsigned long long)c * C) +
             bsum * B;
    }
  for (int b = (0); b < (n); ++b) {
    int nsmaller = 0, nlarger = 0;
    for (int i = (0); i < (((int)(adj[b]).size())); ++i)
      if (adj[b][i] < b)
        ++nsmaller;
      else if (adj[b][i] > b)
        ++nlarger;
    for (int i = (0); i < (((int)(adj[b]).size())); ++i) {
      int a = adj[b][i];
      if (!(a < b)) continue;
      unsigned long long nc = nlarger;
      ret += nc * ((unsigned long long)a * A);
    }
    {
      long long na = nsmaller, nc = nlarger;
      ret += na * nc * ((unsigned long long)b * B);
    }
    for (int i = (0); i < (((int)(adj[b]).size())); ++i) {
      int c = adj[b][i];
      if (!(b < c)) continue;
      unsigned long long na = nsmaller;
      ret += na * ((unsigned long long)c * C);
    }
  }
  for (int a = (0); a < (n); ++a) {
    int nlarger = 0, sofar = 0;
    for (int i = (0); i < (((int)(adj[a]).size())); ++i)
      if (adj[a][i] > a) ++nlarger;
    {
      long long nbc = (long long)nlarger * (nlarger - 1) / 2;
      ret += nbc * ((unsigned long long)a * A);
    }
    for (int i = (0); i < (((int)(adj[a]).size())); ++i) {
      int x = adj[a][i];
      if (!(a < x)) continue;
      int nbefore = sofar, nafter = nlarger - nbefore - 1;
      unsigned long long nb = nbefore, nc = nafter;
      ret +=
          nc * ((unsigned long long)x * B) + nb * ((unsigned long long)x * C);
      ++sofar;
    }
  }
  for (int c = (0); c < (n); ++c) {
    int nsmaller = 0, sofar = 0;
    for (int i = (0); i < (((int)(adj[c]).size())); ++i)
      if (adj[c][i] < c) ++nsmaller;
    for (int i = (0); i < (((int)(adj[c]).size())); ++i) {
      int x = adj[c][i];
      if (!(x < c)) continue;
      int nbefore = sofar, nafter = nsmaller - nbefore - 1;
      unsigned long long na = nbefore, nb = nafter;
      ret +=
          nb * ((unsigned long long)x * A) + na * ((unsigned long long)x * B);
      ++sofar;
    }
    {
      unsigned long long nab = (long long)nsmaller * (nsmaller - 1) / 2;
      ret += nab * ((unsigned long long)c * C);
    }
  }
  counttriangles();
  for (int a = (0); a < (n); ++a)
    ret -= ((unsigned long long)ntrilo[a]) * ((unsigned long long)a * A);
  for (int b = (0); b < (n); ++b)
    ret -= ((unsigned long long)ntrimi[b]) * ((unsigned long long)b * B);
  for (int c = (0); c < (n); ++c)
    ret -= ((unsigned long long)ntrihi[c]) * ((unsigned long long)c * C);
  return ret;
}
void run() {
  scanf("%d%d", &n, &m);
  scanf("%llu%llu%llu", &A, &B, &C);
  for (int i = (0); i < (m); ++i) {
    int a, b;
    scanf("%d%d", &a, &b);
    adj[a].push_back(b);
    adj[b].push_back(a);
  }
  printf("%llu\n", solve());
}
void stress() {
  n = MAXN;
  A = rand() % 1000 * 1000 + rand() % 1000 + 1;
  B = rand() % 1000 * 1000 + rand() % 1000 + 1;
  C = rand() % 1000 * 1000 + rand() % 1000 + 1;
  int nx = 0;
  while ((nx + 2) * (nx + 1) / 2 <= MAXM) ++nx;
  for (int i = (0); i < (nx); ++i)
    for (int j = (i + 1); j < (nx); ++j)
      adj[i].push_back(j), adj[j].push_back(i);
  printf("%llu\n", solve());
}
int main() {
  run();
  return 0;
}