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;
const int N = 200000 + 100;
const int M = 500;
class Solution {
 public:
  Solution(int size, int a, int b, int c, vector<pair<int, int>>& edges)
      : n(size),
        A(a),
        B(b),
        C(c),
        graph(size),
        idx(size, -1),
        smallerSums(size),
        biggerSums(size),
        smallerCnts(size, 0),
        biggerCnts(size, 0),
        aSums(size, 0),
        bSums(size, 0),
        cSums(size, 0) {
    for (auto& p : edges) {
      graph[p.first].push_back(p.second);
      graph[p.second].push_back(p.first);
    }
    for (auto& v : graph) {
      sort(v.begin(), v.end());
    }
    for (int i = 0; i < n; ++i) {
      if (graph[i].size() >= M) {
        idx[i] = connected.size();
        connected.resize(connected.size() + 1);
        for (auto j : graph[i]) {
          connected.back().set(j);
        }
      }
    }
    for (int i = 0; i < n; ++i) {
      unsigned long long sum = 0;
      unsigned long long total = 0;
      int cnt = 0;
      for (auto j : graph[i]) {
        if (j < i) {
          ++cnt;
          sum += j;
          smallerSums[i].push_back(sum);
        }
        total += j;
      }
      smallerCnts[i] = cnt;
      biggerCnts[i] = graph[i].size() - cnt;
      biggerSums[i] = total - sum;
    }
    for (int i = 0; i < n; ++i) {
      aSums[i] = (n - 1 - i - biggerCnts[i]);
      if (i - 1 >= 0) {
        aSums[i] += aSums[i - 1];
      }
    }
    for (int i = 0; i < n; ++i) {
      bSums[i] = (0ULL + n - 1 - i - biggerCnts[i]) * i;
      if (i - 1 >= 0) {
        bSums[i] += bSums[i - 1];
      }
    }
    for (int i = 0; i < n; ++i) {
      cSums[i] =
          (0ULL + i + 1 + n - 1) * (0ULL + n - 1 - i) / 2 - biggerSums[i];
      if (i - 1 >= 0) {
        cSums[i] += cSums[i - 1];
      }
    }
  }
  unsigned long long count() {
    unsigned long long ans = 0;
    unsigned long long a = 0, b = 0, c = 0;
    for (int i = 0; i < n; ++i) {
      unsigned long long ca = aSums[n - 1] - aSums[i];
      unsigned long long cb = bSums[n - 1] - bSums[i];
      unsigned long long cc = cSums[n - 1] - cSums[i];
      for (auto j : graph[i]) {
        if (j > i) {
          ca -= (n - 1 - j) - biggerCnts[j];
          cb -= (0ULL + (n - 1 - j) - biggerCnts[j]) * j;
          cc -= (cSums[j] - cSums[j - 1]);
        }
      }
      for (auto k : graph[i]) {
        if (k > i) {
          auto p = upper_bound(graph[k].begin(), graph[k].end(), i) -
                   graph[k].cbegin();
          unsigned long long sum = smallerSums[k].back();
          if (p - 1 >= 0) {
            sum -= smallerSums[k][p - 1];
          } else {
          }
          unsigned long long as = (k - i - 1 - (smallerCnts[k] - p));
          unsigned long long bs =
              (0ULL + i + 1 + k - 1) * (0ULL + k - i - 1) / 2 - sum;
          unsigned long long cs = as * k;
          ca -= as;
          cb -= bs;
          cc -= cs;
        }
      }
      a += ca * i;
      b += cb;
      c += cc;
    }
    for (int i = 0; i < n; ++i) {
      unsigned long long ca = 0, cb = 0, cc = 0;
      if (idx[i] >= 0) {
        unsigned long long sum = 0;
        for (auto j : graph[i]) {
          sum += j;
        }
        int m = graph[i].size();
        for (int ii = 0; ii < m; ++ii) {
          int j = graph[i][ii];
          sum -= j;
          if (j > i) {
            ca += m - 1 - ii;
            cb += (0ULL + m - 1 - ii) * j;
            cc += sum;
          }
        }
        for (int j = i + 1; j < n; ++j) {
          if (connected[idx[i]][j] == 0) {
            continue;
          }
          for (auto k : graph[j]) {
            if (k <= j) {
              continue;
            }
            if (connected[idx[i]][k]) {
              --ca;
              cb -= j;
              cc -= k;
            }
          }
        }
      } else {
        int m = graph[i].size();
        for (int i1 = 0; i1 < m; ++i1) {
          int j = graph[i][i1];
          if (j <= i) {
            continue;
          }
          if (idx[j] >= 0) {
            for (int i2 = i1 + 1; i2 < m; ++i2) {
              int k = graph[i][i2];
              if (connected[idx[j]][k] == 0) {
                ++ca;
                cb += j;
                cc += k;
              }
            }
          } else {
            for (auto k : graph[j]) {
              gConnected[k] = 1;
            }
            for (int i2 = i1 + 1; i2 < m; ++i2) {
              int k = graph[i][i2];
              if (gConnected[k] == 0) {
                ++ca;
                cb += j;
                cc += k;
              }
            }
            for (auto k : graph[j]) {
              gConnected[k] = 0;
            }
          }
        }
      }
      a += ca * i;
      b += cb;
      c += cc;
    }
    ans = a * A + b * B + c * C;
    return ans;
  }

 private:
  int n;
  int A;
  int B;
  int C;
  vector<vector<int>> graph;
  vector<int> idx;
  vector<bitset<N>> connected;
  bitset<N> gConnected;
  vector<vector<unsigned long long>> smallerSums;
  vector<int> smallerCnts;
  vector<int> biggerCnts;
  vector<unsigned long long> biggerSums;
  vector<unsigned long long> bSums;
  vector<unsigned long long> cSums;
  vector<unsigned long long> aSums;
};
int main(int argc, char** argv) {
  int n, m, a, b, c;
  scanf("%d%d%d%d%d", &n, &m, &a, &b, &c);
  vector<pair<int, int>> edges;
  edges.reserve(m);
  for (int i = 0, u = 0, v = 0; i < m; ++i) {
    scanf("%d%d", &u, &v);
    edges.emplace_back(u, v);
  }
  Solution sol(n, a, b, c, edges);
  printf("%llu\n", sol.count());
  return 0;
}