Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Problem J:
Black Company

JAG Company is a sweatshop (sweatshop is called "burakku kigyo" in Japanese), and you are
the CEO for the company.

You are planning to determine $N$ employees' salary as low as possible (employees are numbered
from 1 to $N$). Each employee's salary amount must be a positive integer greater than zero. At
that time, you should pay attention to the employees' contribution degree. If the employee $i$'s
contribution degree $c_i$ is greater than the employee $j$'s contribution degree $c_j$ , the employee i
must get higher salary than the employee $j$'s salary. If the condition is not satisfied, employees
may complain about their salary amount.

However, it is not necessarily satisfied in all pairs of the employees, because each employee can
only know his/her close employees' contribution degree and salary amount. Therefore, as long as
the following two conditions are satisfied, employees do not complain to you about their salary
amount.

If the employees $i$ and $j$ are close to each other, $c_i < c_j \Leftrightarrow p_i < p_j$ must be satisfied, where
$p_i$ is the employee $i$'s salary amount.

If the employee $i$ is close to the employees $j$ and $k$, $c_j < c_k \Leftrightarrow p_j < p_k$ must be satisfied.
Write a program that computes the minimum sum of all employees' salary amount such that no
employee complains about their salary.

Input

Each input is formatted as follows:

$N$

$c_1$ ... $c_N$

$M$

$a_1$ $b_1$

...

$a_M$ $b_M$

The first line contains an integer $N$ ($1 \leq N \leq 100,000$), which indicates the number of employees.
The second line contains $N$ integers $c_i$ ($1 \leq c_i \leq 100,000$) representing the contribution degree
of employee $i$.

The third line contains an integer $M$ ($0 \leq M \leq 200,000$), which specifies the number of relationships. Each of the following $M$ lines contains two integers $a_i$ and $b_i$ ($a_i \ne b_i, 1 \leq a_i, b_i \leq N$).
It represents that the employees $a_i$ and $b_i$ are close to each other. There is no more than one
relationship between each pair of the employees.

Output

Print the minimum sum of all employees' salary amounts in a line.

Sample Input

3
1 3 3
2
1 2
1 3

Output for the Sample Input

5

Sample Input

3
1 2 3
2
1 2
1 3

Output for the Sample Input

6

Sample Input

4
1 1 2 2
2
1 2
3 4

Output for the Sample Input

4

Sample Input

5
1 2 5 5 1
6
1 2
4 1
2 3
5 2
4 3
4 5

Output for the Sample Input

10

Sample Input

6
4 3 2 1 5 3
7
4 2
1 5
2 6
6 5
4 1
1 6
6 3

Output for the Sample Input

13

Solution in C++11 (judge verdict: Wrong Answer)

#include <bits/stdc++.h>

using namespace std;

#define int long long

const int inf = 1LL<<55;//INT_MAX;

using vint = vector<int>;
using Graph1 = vector<vint>;
using Graph2 = vector<set<int>>;

struct UnionFind {
  vint data;
  UnionFind(int N):data(N, -1){}
  int find(int x) {
    return data[x] < 0 ? x : data[x] = find(data[x]);
  }
  int size(int x) {
    return -data[find(x)];
  }
  bool same(int x, int y) {
    return find(x) == find(y);
  }
  bool unite(int x, int y) {
    x = find(x), y = find(y);
    if(x == y) return false;
    if(data[x] < data[y]) swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return true;
  }
};

#define MAX_N 100000

int N, M;
vint c;
Graph1 graph;
Graph2 dag;

vector<int> tsort(const Graph2& g) {
  int n = graph.size(), k = 0;
  vint in(n), used(n), ord;
  for(int u = 0; u < n; u++) {
    for(int v : g[u]) in[v]++;
  }
  queue<int> que;
  for(int u = 0; u < n; u++) {
    if(!in[u]) {
      used[u] = true;
      que.push(u);
    }
  }
  while(!que.empty()) {
    int u = que.front(); que.pop();
    ord.push_back(u);
    for(int v : g[u]) {
      in[v]--;
      if(!in[v] && !used[v]) {
	used[v] = true;
	que.push(v);
      }
    }
  }
  return ord;
}

int dp[MAX_N];

signed main() {
  cin >> N;
  graph.resize(N);
  c.resize(N);
  for(int i = 0; i < N; i++) cin >> c[i];
  vint id(N);
  iota(id.begin(), id.end(), 0);
  sort(id.begin(), id.end(), [&](int i, int j){
      return c[i] < c[j];
    });
  map<int, int> mp;
  for(int i = 0; i < N; i++) mp[id[i]] = i;
  sort(c.begin(), c.end());
  cin >> M;
  for(int i = 0; i < M; i++) {
    int a, b;
    cin >> a >> b;
    --a, --b;
    a = mp[a];//id[a];
    b = mp[b];//id[b];
    graph[a].push_back(b);
    graph[b].push_back(a);
  }
  UnionFind uf(N);
  for(int i = 0; i < N; i++) {
    graph[i].push_back(i);
    sort(graph[i].begin(), graph[i].end());
    for(int j = 1; j < (int)graph[i].size(); j++) {
      int u = graph[i][j-1];
      int v = graph[i][j];
      if(c[u] == c[v]) uf.unite(u, v);
    }
  }
  dag.resize(N);
  for(int i = 0; i < N; i++) {
    for(int j = 1; j < (int)graph[i].size(); j++) {
      int u = graph[i][j-1];//uf.find(graph[i][j-1]);
      int v = graph[i][j];//uf.find(graph[i][j]);
      if(c[u] == c[v]) continue;
      //cout << i << ":"<<u << " " << v << endl;
      if(u != v) dag[uf.find(u)].insert(v);
    }
  }
  /*
  for(int i = 0; i < N; i++) {
    cout << i << ":";
    for(int v : dag[i]) cout << v << " ";
    cout << endl;
  }
  */
  auto ord = tsort(dag);
  //assert(ord.size() == N);
  for(int i = 0; i < N; i++) dp[i] = 1;
  for(int u : ord) {
    for(int v : dag[uf.find(u)]) dp[uf.find(v)] = max(dp[uf.find(v)], dp[uf.find(u)]+1);
  }
  int ans = 0;
  for(int i = 0; i < N; i++) {
    if(i != uf.find(i)) continue;
    //cout << dp[i] << endl;
    ans += dp[i]*uf.size(i);
  }
  cout << ans << endl;

  return 0;
}