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 std ::sort;
using std ::swap;
template <typename T>
T max(T x, T y) {
  return (x > y) ? x : y;
}
template <typename T>
T min(T x, T y) {
  return (x < y) ? x : y;
}
template <typename T>
bool chkmax(T &x, T y) {
  return (x >= y) ? 0 : (x = y, 1);
}
template <typename T>
bool chkmin(T &x, T y) {
  return (x <= y) ? 0 : (x = y, 1);
}
template <typename T>
T read(T &in) {
  in = 0;
  char ch;
  T f = 1;
  while (!isdigit(ch = getchar()))
    if (ch == '-') f = -1;
  while (isdigit(ch)) in = in * 10 + ch - '0', ch = getchar();
  return in *= f;
}
static const int max1 = 200000 + 11;
static const int max2 = 400000 + 11;
struct hash_table {
  static const int MOD = 8314777;
  int cnt;
  hash_table() { cnt = MOD; }
  struct unit {
    int next, x, y;
    unit() { next = x = y = -1; }
  } T[MOD + max1];
  void Insert(int x, int y) {
    if (x > y) swap(x, y);
    int c = (200000ll * x + y) % MOD;
    if (~T[c].x) {
      T[c].x = x, T[c].y = y;
    } else {
      while (~T[c].next) c = T[c].next;
      T[c].next = ++cnt, T[cnt].x = x, T[cnt].y = y;
    }
  }
  bool operator()(int x, int y) {
    if (x > y) swap(x, y);
    int c = (200000ll * x + y) % MOD;
    while (~c && (T[c].x != x || T[c].y != y)) c = T[c].next;
    return ~c;
  }
} o;
int Ct, Ht[max1], Nt[max2], to[max2];
void ins(int x, int y) {
  Nt[++Ct] = Ht[x], Ht[x] = Ct, to[Ct] = y;
  Nt[++Ct] = Ht[y], Ht[y] = Ct, to[Ct] = x;
}
int n, m;
int sc[3];
int ex[max1], ey[max1], ind[max1];
int cnt[max1][3][4], isB[max1];
unsigned long long C2(int n) { return 1ull * n * (n - 1) >> 1; }
unsigned long long sigma(int l, int r) {
  return 1ull * (l + r) * (r - l + 1) >> 1;
}
unsigned long long Get0() {
  unsigned long long res = 0;
  for (int i = (0), ir = (n - 1); i <= (ir); ++i) {
    int a = i, b = n - 1 - i;
    res += i * (C2(a) * sc[2] + 1ull * a * b * sc[1] + C2(b) * sc[0]);
  }
  return res;
}
unsigned long long Get1() {
  unsigned long long res = 0;
  for (int _ = (1), _r = (m); _ <= (_r); ++_) {
    int x = ex[_], y = ey[_];
    int a = x, b = y - x - 1, c = n - 1 - y;
    res += 1ull * sc[0] * sigma(0, x - 1) + 1ull * sc[1] * a * x +
           1ull * sc[2] * a * y;
    res += 1ull * sc[0] * b * x + 1ull * sc[2] * b * y +
           1ull * sc[1] * sigma(x + 1, y - 1);
    res += 1ull * sc[0] * c * x + 1ull * sc[1] * c * y +
           1ull * sc[2] * sigma(y + 1, n - 1);
  }
  return res;
}
unsigned long long Get2() {
  unsigned long long res = 0;
  for (int x = (0), xr = (n - 1); x <= (xr); ++x) {
    int a = 0, b = 0;
    for (int i = (Ht[x]); i; i = (Nt[i]))
      if (to[i] < x)
        ++a;
      else
        ++b;
    res += x * (C2(a) * sc[2] + 1ull * a * b * sc[1] + C2(b) * sc[0]);
    static int q[max1];
    q[0] = 0;
    for (int i = (Ht[x]); i; i = (Nt[i])) q[++q[0]] = to[i];
    sort(1 + q, 1 + q + q[0]);
    for (int _ = (1), _r = (a); _ <= (_r); ++_) {
      int i = q[_];
      res += i * (1ull * (_ - 1) * sc[1] + 1ull * (q[0] - _) * sc[0]);
    }
    for (int _ = (a + 1), _r = (q[0]); _ <= (_r); ++_) {
      int i = q[_];
      res += i * (1ull * (q[0] - _) * sc[1] + 1ull * (_ - 1) * sc[2]);
    }
  }
  return res;
}
unsigned long long Get3() {
  int M = (int)sqrt(m);
  for (int i = (1), ir = (m); i <= (ir); ++i) o.Insert(ex[i], ey[i]);
  for (int i = (0), ir = (n - 1); i <= (ir); ++i) isB[i] = ind[i] >= M;
  for (int i = (0), ir = (n - 1); i <= (ir); ++i)
    if (isB[i]) {
      for (int j = (1), jr = (m); j <= (jr); ++j) {
        int x = ex[j], y = ey[j];
        if (x <= i || y <= i) continue;
        if (o(i, x) && o(i, y)) {
          int type = 3 - (1 + isB[x] + isB[y]);
          cnt[i][(x < i) + (y < i)][type]++;
          cnt[x][(i < x) + (y < x)][type]++;
          cnt[y][(i < y) + (x < y)][type]++;
        }
      }
    }
  for (int _ = (1), _r = (m); _ <= (_r); ++_) {
    int x = ex[_], y = ey[_];
    if (!isB[x]) {
      for (int i = (Ht[x]); i; i = (Nt[i])) {
        int w = to[i];
        if (w == y || w < x || w > y) continue;
        if (o(w, y)) {
          int type = 3 - (isB[y] + isB[w]);
          cnt[w][(x < w) + (y < w)][type]++;
          cnt[x][(w < x) + (y < x)][type]++;
          cnt[y][(w < y) + (x < y)][type]++;
        }
      }
    }
  }
  unsigned long long res = 0;
  for (int i = (0), ir = (n - 1); i <= (ir); ++i)
    for (int j = (0), jr = (2); j <= (jr); ++j)
      for (int k = (0), kr = (3); k <= (kr); ++k)
        res += 1ull * cnt[i][j][k] * i * sc[j];
  return res;
}
int main() {
  read(n), read(m);
  for (int i = (0), ir = (2); i <= (ir); ++i) read(sc[i]);
  for (int i = (1), ir = (m); i <= (ir); ++i) {
    int &x = ex[i], &y = ey[i];
    read(x), read(y);
    if (x > y) swap(x, y);
    ins(x, y), ind[x]++, ind[y]++;
  }
  printf("%llu\n", Get0() - Get1() + Get2() - Get3());
  return 0;
}