Problem:
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

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
      
#define FOR(i,a,b) for( ll i = (a); i < (ll)(b); i++ )
#define REP(i,n) FOR(i,0,n)
#define YYS(x,arr) for(auto& x:arr)
#define ALL(x) (x).begin(),(x).end()
#define SORT(x) sort( (x).begin(),(x).end() )
#define REVERSE(x) reverse( (x).begin(),(x).end() )
#define UNIQUE(x) (x).erase( unique( ALL( (x) ) ) , (x).end() )
#define PW(x) (1LL<<(x))
#define SZ(x) ((ll)(x).size())
#define SHOW(x) cout << #x << " = " << x << endl
#define SHOWA(x,n) for( int yui = 0; yui < n; yui++ ){ cout << x[yui] << " "; } cout << endl

#define pb emplace_back
#define fi first
#define se second

using namespace std;

typedef long double ld;
typedef long long int ll;
typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<bool> vb;
typedef vector<ld> vd;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<vpl> gr;
typedef vector<vl> ml;
typedef vector<vd> md;
typedef vector<vi> mi;
     
const ll INF = (ll)1e9 + 10;
const ll INFLL = (ll)1e18 + 10;
const ld EPS = 1e-12;
const ll MOD = 1e9+7;
     
template<class T> T &chmin( T &a , const T &b ){ return a = min(a,b); }
template<class T> T &chmax( T &a , const T &b ){ return a = max(a,b); }
template<class T> inline T sq( T a ){ return a * a; }

ll in(){ long long int x; scanf( "%lld" , &x ); return x; }
char yuyushiki[1000010]; string stin(){ scanf( "%s" , yuyushiki ); return yuyushiki; }

// head

struct Unionfind{
  vi size, par;
  Unionfind(){}
  Unionfind( int n ) :  size(n,1), par(n){
    REP( i , n ) par[i] = i;
  }
  void init( int n ){
    size = vi( n , 1 );
    par.resize( n );
    REP( i , n ) par[i] = i;
  }
  int find( int x ){
    if( par[x] == x ) return x;
    return par[x] = find( par[x] );
  }
  bool unite( int x , int y ){
    x = find(x);
    y = find(y);
    if( x == y ) return false;
    if( size[y] < size[x] ) swap( x , y );
    par[x] = y;
    size[y] += size[x];
    return true;
  }
  bool same( int x , int y ){
    return find(x) == find(y);
  }
};

int n, m;
ll c[100010];

Unionfind uf;

bool used[100010];
ll val[100010];

vi G[100010];
vi GG[100010];

ll ans;

void dfs( int x ){
  used[x] = true;
  val[x] = 0;
  YYS( w , GG[x] ){
    if( !used[w] ){
      dfs( w );
    }
    chmax( val[x] , val[w] );
  }
  val[x]++;
}

int main(){

  n = in();
  REP( i , n ){
    c[i] = in();
  }
  m = in();
  REP( i , m ){
    int a = in() - 1;
    int b = in() - 1;
    G[a].pb( b );
    G[b].pb( a );
  }

  uf.init( n );
  REP( i , n ){
    vpi v(0);
    v.pb( c[i] , i );
    YYS( w , G[i] ){
      v.pb( c[w] , w );
    }
    SORT( v );
    REP( i , SZ(v)-1 ){
      if( v[i].fi == v[i+1].fi ){
        uf.unite( v[i].se , v[i+1].se );
      }
    }
  }

  REP( i , n ){
    vpi v(0);
    v.pb( c[i] , i );
    YYS( w , G[i] ){
      v.pb( c[w] , w );
    }
    SORT( v );
    REP( i , SZ(v)-1 ){
      if( v[i].fi != v[i+1].fi ){
        int hi = uf.find( v[i+1].se );
        int lo = uf.find( v[i].se );
        // cout << hi << " " << lo << endl;
        GG[ hi ].pb( lo );
      }
    }
  }


  REP( i , n ){
    if( !used[ uf.find( i ) ] ){
      dfs( uf.find( i ) );
    }
  }

  /*
  REP( i , n ){
    cout << val[i] << endl;
  }
  */

  REP( i , n ){
    ans += val[ uf.find( i ) ];
  }

  printf( "%lld\n" , ans );
  
  return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 20720
final_rank: 3

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

struct UnionFind{
    vector<int> par; int n;
    UnionFind(){}
    UnionFind(int _n):par(_n,-1),n(_n){}
    int root(int x){return par[x]<0?x:par[x]=root(par[x]);}
    bool same(int x,int y){return root(x)==root(y);}
    int size(int x){return -par[root(x)];}
    bool unite(int x,int y){
        x=root(x),y=root(y); if(x==y)return false;
        if(size(x)>size(y))swap(x,y);
        par[y]+=par[x]; par[x]=y; n--; return true;
    }
};

/**
 * @brief Union Find
 */

int main() {
    int N;
    cin >> N;
    vector<int> C(N);
    rep(i,0,N) cin >> C[i];
    UnionFind UF(N);
    int M;
    cin >> M;
    vector<int> A(M), B(M);
    vector<vector<int>> G(N);
    rep(i,0,M) {
        cin >> A[i] >> B[i];
        A[i]--, B[i]--;
        G[A[i]].push_back(B[i]);
        G[B[i]].push_back(A[i]);
        if (C[A[i]] == C[B[i]]) UF.unite(A[i],B[i]);
    }
    rep(i,0,N) {
        if (G[i].empty()) continue;
        sort(ALL(G[i]),[&](int a, int b){return C[a] < C[b];});
        rep(j,0,G[i].size()-1) {
            if (C[G[i][j]] == C[G[i][j+1]]) UF.unite(G[i][j],G[i][j+1]);
        }
    }
    vector<vector<int>> H(N);
    rep(i,0,M) {
        int S = A[i], T = B[i];
        if (C[S] == C[T]) continue;
        if (C[S] > C[T]) swap(S,T);
        S = UF.root(S), T = UF.root(T);
        H[S].push_back(T);
    }
    rep(i,0,N) {
        if (G[i].empty()) continue;
        rep(j,0,G[i].size()-1) {
            int S = G[i][j], T = G[i][j+1];
            if (C[S] == C[T]) continue;
            if (C[S] > C[T]) swap(S,T);
            S = UF.root(S), T = UF.root(T);
            H[S].push_back(T);
        }
    }
    vector<int> DP(N,1);
    vector<int> ord(N);
    iota(ALL(ord),0);
    sort(ALL(ord),[&](int i, int j){return C[i]<C[j];});
    for (int i : ord) {
        if (i != UF.root(i)) continue;
        for (int j : H[i]) {
            chmax(DP[j],DP[i]+1);
        }
    }
    ll ANS = 0;
    rep(i,0,N) {
        ANS += DP[UF.root(i)];
    }
    cout << ANS << endl;
}
accuracy: 1
time_ms: 120
memory_kb: 18756
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;

long long solve(int N, int M, vector<int> C, vector<int> A, vector<int> B) {
	// step #1. make graph
	vector<vector<int> > G(N);
	for (int i = 0; i < M; i++) {
		G[A[i]].push_back(B[i]);
		G[B[i]].push_back(A[i]);
	}

	// step #2. compression of C[i]'s
	vector<int> comp = C;
	sort(comp.begin(), comp.end());
	comp.erase(unique(comp.begin(), comp.end()), comp.end());
	for (int i = 0; i < N; i++) {
		C[i] = lower_bound(comp.begin(), comp.end(), C[i]) - comp.begin();
	}
	int L = comp.size();
	vector<vector<int> > V(L);
	for (int i = 0; i < N; i++) {
		V[C[i]].push_back(i);
	}

	// step #3. calculation
	vector<int> level(N, -1), maxadj(N, -1);
	for (int i = 0; i < L; i++) {
		for (int j : V[i]) {
			level[j] = 1;
			for (int k : G[j]) {
				level[j] = max(level[j], maxadj[k] + 1);
			}
		}
		for (int j : V[i]) {
			maxadj[j] = max(maxadj[j], level[j]);
			for (int k : G[j]) {
				maxadj[k] = max(maxadj[k], level[j]);
			}
		}
	}

	// step #4. calculate answer
	long long ans = 0;
	for (int i = 0; i < N; i++) {
		ans += level[i];
	}

	return ans;
}

long long solve_easy(int N, int M, vector<int> C, vector<int> A, vector<int> B) {
	vector<vector<int> > G(N);
	for (int i = 0; i < M; i++) {
		G[A[i]].push_back(B[i]);
		G[B[i]].push_back(A[i]);
	}
	vector<vector<int> > H = G;
	for (int i = 0; i < N; i++) {
		for (int j : G[i]) {
			for (int k : G[j]) {
				if (j != k) {
					H[i].push_back(k);
				}
			}
		}
	}
	for (int i = 0; i < N; i++) {
		sort(H[i].begin(), H[i].end());
		H[i].erase(unique(H[i].begin(), H[i].end()), H[i].end());
	}
	vector<int> perm(N);
	for (int i = 0; i < N; i++) {
		perm[i] = i;
	}
	sort(perm.begin(), perm.end(), [&](int va, int vb) {
		return C[va] < C[vb];
	});
	vector<int> level(N, 1);
	for (int i : perm) {
		for (int j : H[i]) {
			if (C[j] < C[i]) {
				level[i] = max(level[i], level[j] + 1);
			}
		}
	}
	long long ans = 0;
	for (int i = 0; i < N; i++) {
		ans += level[i];
	}
	return ans;
}

int main() {
	// step #1. input
	cin.tie(0);
	ios::sync_with_stdio(false);
	int N;
	cin >> N;
	vector<int> C(N);
	for (int i = 0; i < N; i++) {
		cin >> C[i];
	}
	int M;
	cin >> M;
	vector<int> A(M), B(M);
	for (int i = 0; i < M; i++) {
		cin >> A[i] >> B[i];
		A[i] -= 1;
		B[i] -= 1;
	}
	long long ans = solve_easy(N, M, C, A, B);
	cout << ans << endl;
	return 0;
}
accuracy: 0.22580645161290322
time_ms: 510
memory_kb: 61748
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
	// step #1. input
	int N;
	cin >> N;
	vector<int> C(N);
	for (int i = 0; i < N; i++) {
		cin >> C[i];
	}
	int M;
	cin >> M;
	vector<vector<int> > G(N);
	for (int i = 0; i < M; i++) {
		int a, b;
		cin >> a >> b;
		G[a - 1].push_back(b - 1);
		G[b - 1].push_back(a - 1);
	}

	// step #2. compression of C[i]'s
	vector<int> comp = C;
	sort(comp.begin(), comp.end());
	comp.erase(unique(comp.begin(), comp.end()), comp.end());
	for (int i = 0; i < N; i++) {
		C[i] = lower_bound(comp.begin(), comp.end(), C[i]) - comp.begin();
	}
	int L = comp.size();
	vector<vector<int> > V(L);
	for (int i = 0; i < N; i++) {
		V[C[i]].push_back(i);
	}

	// step #3. calculation
	vector<int> level(N, -1), maxadj(N, -1);
	for (int i = 0; i < L; i++) {
		for (int j : V[i]) {
			level[j] = 1;
			for (int k : G[j]) {
				level[j] = max(level[j], maxadj[k] + 1);
			}
		}
		for (int j : V[i]) {
			maxadj[j] = max(maxadj[j], level[j]);
			for (int k : G[j]) {
				maxadj[k] = max(maxadj[k], level[j]);
			}
		}
	}

	// step #4. calculate answer
	long long ans = 0;
	for (int i = 0; i < N; i++) {
		ans += level[i];
	}

	// step #5. output
	cout << ans << endl;

	return 0;
}
accuracy: 0.22580645161290322
time_ms: 100
memory_kb: 16084
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
	// step #1. input
	int N;
	cin >> N;
	vector<int> C(N);
	for (int i = 0; i < N; i++) {
		cin >> C[i];
	}
	int M;
	cin >> M;
	vector<vector<int> > G(N);
	for (int i = 0; i < M; i++) {
		int a, b;
		cin >> a >> b;
		G[a - 1].push_back(b - 1);
		G[b - 1].push_back(a - 1);
	}

	// step #2. compression of C[i]'s
	vector<int> comp = C;
	sort(comp.begin(), comp.end());
	comp.erase(unique(comp.begin(), comp.end()), comp.end());
	for (int i = 0; i < N; i++) {
		C[i] = lower_bound(comp.begin(), comp.end(), C[i]) - comp.begin();
	}
	int L = comp.size();
	vector<vector<int> > V(L);
	for (int i = 0; i < N; i++) {
		V[C[i]].push_back(i);
	}

	// step #3. calculation
	vector<int> level(N, -1), maxadj(N, -1);
	for (int i = 0; i < L; i++) {
		for (int j : V[i]) {
			level[j] = 1;
			for (int k : G[j]) {
				if (C[k] < i) {
					level[j] = max(level[j], maxadj[k] + 1);
				}
			}
		}
		for (int j : V[i]) {
			maxadj[j] = max(maxadj[j], level[j]);
			for (int k : G[j]) {
				maxadj[k] = max(maxadj[k], level[j]);
			}
		}
	}

	// step #4. calculate answer
	long long ans = 0;
	for (int i = 0; i < N; i++) {
		ans += level[i];
	}

	// step #5. output
	cout << ans << endl;

	return 0;
}
accuracy: 0.08064516129032258
time_ms: 30
memory_kb: 4808
final_rank: 20

code_snippet: #include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int,int> P;

int main(){
	int n; cin>>n;
	vector<vector<int>> a(1000005);
	vector<int> c(n);
	for(int i=0; i<n; i++){
		int k; cin>>k;
		a[k].push_back(i);
		c[i] = k;
	}

	vector<vector<int>> g(n);
	int m; cin>>m;
	for(int i= 0; i<m; i++){
		int a,b; cin>>a>>b;
		a--; b--;
		g[a].push_back(b);
		g[b].push_back(a);
	}

	vector<P> x(n);
	vector<int> ans(n);

	for(int i = 0; i< 1000005; i++){
	for(int r : a[i]){
		//cout<<r<<endl;
		//get ans;
		for(int t : g[r]){
			//if(ans[r] <= x[t].first){

			ans[r] = max(ans[r],x[t].first);
	//		cout<<t<<" "<<x[t].first<<endl;
			//	if(c[r] != x[t].second) ans[r]++;
		}
		ans[r]++;
	}
	for(int r : a[i]){
		x[r].first = max(x[r].first,ans[r]);

		for(int t : g[r]){
			if(x[t].first <= ans[r]){

				x[t].first = ans[r];
			
			}
		}
	}
	}
	ll res = 0;
	for(int i = 0; i<n; i++){
		res += ans[i];
	//	cout<<ans[i]<<endl;
	}
	cout<<res<<endl;
}
accuracy: 0.22580645161290322
time_ms: 90
memory_kb: 37604
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

struct compress {
        vector<int> C;
        compress(vector<int> A) : C(A) {
                sort(C.begin(), C.end());
                C.erase(unique(C.begin(), C.end()), C.end());
        }
        int operator[](int v) const {
                return lower_bound(C.begin(), C.end(), v) - C.begin();
        }
        size_t size() const {
                return C.size();
        }
};

template <class T>
void out(vector<T> A) {
        for (auto a : A) cout << a << ' ';
        cout << endl;
}

int main() {
        int N; cin >> N;
        vector C(N, 0);
        for (auto& c : C) cin >> c;
        compress comp(C);

        vector<vector<int>> info(comp.size());
        for (int i = 0 ; i < N ; i++) {
                info[comp[C[i]]].push_back(i);
        }

        int M; cin >> M;

        vector<vector<int>> G(N);
        for (int _ = 0 ; _ < M ; _++) {
                int a, b; cin >> a >> b;
                a--; b--;
                G[a].push_back(b);
                G[b].push_back(a);
        }

        vector<int> adj(N, 0);
        vector<int> ans(N, 0);
        for (const auto& arr : info) {
                { // decide
                        for (auto v : arr) {
                                int val = adj[v];
                                for (auto x : G[v]) {
                                        val = max(val, adj[x]);
                                }
                                val++;
                                ans[v] = val;
                        }
                }
                { // kousin
                        for (auto v : arr) {
                                adj[v] = max(adj[v], ans[v]);
                                for (auto x : G[v]) {
                                        adj[x] = max(adj[x], ans[v]);
                                }
                        }
                }
        }
        
        long long ans_sum = accumulate(ans.begin(), ans.end(), 0LL);
        cout << ans_sum << endl;
}
accuracy: 0.22580645161290322
time_ms: 100
memory_kb: 16448
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;

struct compress {
        vector<int> C;
        compress(vector<int> A) : C(A) {
                sort(C.begin(), C.end());
                C.erase(unique(C.begin(), C.end()), C.end());
        }
        int operator[](int v) const {
                return lower_bound(C.begin(), C.end(), v) - C.begin();
        }
        size_t size() const {
                return C.size();
        }
};

template <class T>
void out(vector<T> A) {
        for (auto a : A) cout << a << ' ';
        cout << endl;
}

int main() {
        int N; cin >> N;
        vector C(N, 0);
        for (auto& c : C) cin >> c;
        compress comp(C);

        vector<vector<int>> info(comp.size());
        for (int i = 0 ; i < N ; i++) {
                info[comp[C[i]]].push_back(i);
        }

        int M; cin >> M;

        vector<vector<int>> G(N);
        for (int _ = 0 ; _ < M ; _++) {
                int a, b; cin >> a >> b;
                a--; b--;
                G[a].push_back(b);
                G[b].push_back(a);
        }

        vector<int> adj(N, 0);
        vector<int> ans(N, 0);
        for (const auto& arr : info) {
                { // decide
                        for (auto v : arr) {
                                int val = 0;
                                for (auto x : G[v]) {
                                        val = max(val, adj[x]);
                                }
                                val++;
                                ans[v] = val;
                        }
                }
                { // kousin
                        for (auto v : arr) {
                                adj[v] = ans[v];
                                for (auto x : G[v]) {
                                        adj[x] = max(adj[x], ans[v]);
                                }
                        }
                }
        }
        
        long long ans_val = accumulate(ans.begin(), ans.end(), 0LL);
        cout << ans_val << endl;
}
accuracy: 0.22580645161290322
time_ms: 100
memory_kb: 16252
final_rank: 10

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int N, C[200009];
int M, A[200009], B[200009];
int Max_Neighbor[200009];
int Max_Color[200009];
int Answer[200009];

// Graph / Vector
int Color[200009], Components = 0;
vector<int> G[200009];
vector<int> H[200009];
vector<int> Contrib[200009];

void dfs(int pos) {
	Color[pos] = Components;
	for (int i : H[pos]) {
		if (Color[i] != 0) continue;
		dfs(i);
	}
}

int main() {
	// Input
	cin >> N;
	for (int i = 1; i <= N; i++) {
		cin >> C[i];
		Contrib[C[i]].push_back(i);
	}
	cin >> M;
	for (int i = 1; i <= M; i++) {
		cin >> A[i] >> B[i];
		G[A[i]].push_back(B[i]);
		G[B[i]].push_back(A[i]);
	}
	
	// Add Edges
	for (int i = 1; i <= M; i++) {
		if (C[A[i]] == C[B[i]]) {
			H[A[i]].push_back(B[i]);
			H[B[i]].push_back(A[i]);
		}
	}
	for (int i = 1; i <= N; i++) {
		vector<pair<int, int>> tmp;
		for (int j : G[i]) tmp.push_back(make_pair(C[j], j));
		sort(tmp.begin(), tmp.end());
		for (int j = 0; j < (int)tmp.size() - 1; j++) {
			if (tmp[j].first != tmp[j+1].first) continue;
			int idx1 = tmp[j].second;
			int idx2 = tmp[j+1].second;
			H[idx1].push_back(idx2);
			H[idx2].push_back(idx1);
		}
	}
	
	// Decomposition
	for (int i = 1; i <= N; i++) {
		if (Color[i] != 0) continue;
		Components += 1;
		dfs(i);
	}
	
	// Greedy
	for (int i = 1; i <= 100000; i++) {
		for (int idx : Contrib[i]) {
			int ret = Max_Neighbor[idx];
			for (int to : G[idx]) ret = max(ret, Max_Neighbor[to]);
			Max_Color[Color[idx]] = max(Max_Color[Color[idx]], ret + 1);
		}
		for (int idx : Contrib[i]) {
			Answer[idx] = Max_Color[Color[idx]];
		}
		for (int idx : Contrib[i]) {
			Max_Neighbor[idx] = max(Max_Neighbor[idx], Answer[idx]);
			for (int to : G[idx]) Max_Neighbor[to] = max(Max_Neighbor[to], Answer[idx]);
		}
	}
	
	// Output
	long long FinalAns = 0;
	for (int i = 1; i <= N; i++) FinalAns += Answer[i];
	cout << FinalAns << endl;
	return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 29640
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int N, C[200009];
int M, A[200009], B[200009];
int Max_Neighbor[200009];
int Answer[200009];
vector<int> G[200009];
vector<int> Contrib[200009];

int main() {
	// Input
	cin >> N;
	for (int i = 1; i <= N; i++) {
		cin >> C[i];
		Contrib[C[i]].push_back(i);
	}
	cin >> M;
	for (int i = 1; i <= M; i++) {
		cin >> A[i] >> B[i];
		G[A[i]].push_back(B[i]);
		G[B[i]].push_back(A[i]);
	}
	
	// Greedy
	for (int i = 1; i <= 100000; i++) {
		for (int idx : Contrib[i]) {
			int ret = Max_Neighbor[idx];
			for (int to : G[idx]) ret = max(ret, Max_Neighbor[to]);
			Answer[idx] = ret + 1;
		}
		for (int idx : Contrib[i]) {
			Max_Neighbor[idx] = max(Max_Neighbor[idx], Answer[idx]);
			for (int to : G[idx]) Max_Neighbor[to] = max(Max_Neighbor[to], Answer[idx]);
		}
	}
	
	// Output
	long long FinalAns = 0;
	for (int i = 1; i <= N; i++) FinalAns += Answer[i];
	cout << FinalAns << endl;
	return 0;
}
accuracy: 0.22580645161290322
time_ms: 90
memory_kb: 23076
final_rank: 12

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int N, C[200009];
int M, A[200009], B[200009];
int Max_Neighbor[200009];
int Answer[200009];
vector<int> G[200009];
vector<int> Contrib[200009];

int main() {
	// Input
	cin >> N;
	for (int i = 1; i <= N; i++) {
		cin >> C[i];
		Contrib[C[i]].push_back(i);
	}
	cin >> M;
	for (int i = 1; i <= M; i++) {
		cin >> A[i] >> B[i];
		G[A[i]].push_back(B[i]);
		G[B[i]].push_back(A[i]);
	}
	
	// Greedy
	for (int i = 1; i <= 100000; i++) {
		for (int idx : Contrib[i]) {
			int ret = 0;
			for (int to : G[idx]) ret = max(ret, Max_Neighbor[to]);
			Answer[idx] = ret + 1;
		}
		for (int idx : Contrib[i]) {
			Max_Neighbor[idx] = max(Max_Neighbor[idx], Answer[idx]);
			for (int to : G[idx]) Max_Neighbor[to] = max(Max_Neighbor[to], Answer[idx]);
		}
	}
	
	// Output
	long long FinalAns = 0;
	for (int i = 1; i <= N; i++) FinalAns += Answer[i];
	cout << FinalAns << endl;
	return 0;
}
accuracy: 0.22580645161290322
time_ms: 90
memory_kb: 23148
final_rank: 13

code_snippet: #define eb emplace_back
#define pb push_back
#define pii pair<int,int>
#define sz(x) int((x).size())
#define ALL(x) (x).begin(),(x).end()
#define ln cout << '\n'
#define REP(i, a) for (int i = 0; i < int(a); i++)
#define FOR(i, a) for (int i = 1; i <= int(a); i++)
#define _ok(x, y) (x >= 0 && x < n && y >= 0 && y < m)
#define MEM(a,b) memset((a),(b),sizeof(a))
#define debug(x) cout << "(" << __LINE__ << ") " << #x << " = " << x << "\n";
const int INF = 0x3f3f3f3f;
const int MOD =  998244353;
using namespace std;
#include <bits/stdc++.h>
using ll = long long;
using vi = vector<int>;
template<typename T> void rd(vector<T> &a) {for (auto &ele : a) cin >> ele;}
template<typename T> void writeln(vector<T> &a) {for (auto &ele : a) cout << ele << ' '; cout << "\n";}
#if __cplusplus > 201402L
template<typename... Args> void rd(Args&... args) {((cin >> args), ...);}
template<typename... Args> void write(Args... args) {((cout << args << " "), ...);}
template<typename... Args> void writeln(Args... args) {((cout << args << " "), ...); cout << "\n";}
#endif
#define int ll
const int maxn = 1e5 + 5;
int c[maxn];
int res[maxn];
vi a[maxn];
void solve() {
    int n;
    cin >> n;
    FOR(i, n) cin >> c[i];
    int mi = *min_element(c + 1, c + n + 1);
//    writeln(mi);
    priority_queue<pii, vector<pii>, greater<>> q;
    vector<int> vis(n + 1);
    FOR(i, n) {
        if (c[i] == mi) {
            res[i] = 1;
            vis[i] = 1;
            q.emplace(1, i);

        }
    }
    int m;
    cin >> m;
    REP(i, m) {
        int u, v;
        cin >> u >> v;
        a[u].eb(v);
        a[v].eb(u);
    }
    while (!q.empty()) {
        auto [d, x] = q.top(); q.pop();
//        if (vis[x]) continue;
//        vis[x] = 1;
//        writeln("at", x, d);
        auto& v = a[x];
        sort(ALL(v), [&](int a, int b) {
            return c[a] < c[b];
        });
        int last = d;
        int lastc = c[x];
        for (auto to : v) {
            if (vis[to]) continue;
            vis[to] = 1;
            if (c[to] > lastc) {
                res[to] = last + 1;
                q.emplace(res[to], to);
                last++;
                lastc = c[to];
            } else {
                res[to] = last;
            }
        }
    }
    FOR(i, n) {
        if (!res[i]) {
            res[i] = 1;
        }
    }
    int sum{};
    FOR(i, n) sum += res[i];
//    FOR(i, n) write(res[i]); ln;
    cout << sum << "\n";

}

signed main()
{
/*#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", +stdin);
    freopen("output.txt", "w", stdout);
#endif*/
    cin.tie(0)->sync_with_stdio(false);
    solve();
//	int t;cin >> t;while(t--) solve();
    return 0;
}
accuracy: 0.08064516129032258
time_ms: 10
memory_kb: 7292
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;

struct UnionFind {
    UnionFind(int n) : n(n), num(n), data(n, -1) {}

    int find(int x) {
        assert(0 <= x && x < n);
        return data[x] < 0 ? x : data[x] = find(data[x]);
    }

    bool merge(int x, int y) {
        assert(0 <= x && x < n);
        assert(0 <= y && y < n);
        if ((x = find(x)) == (y = find(y))) return false;
        if (-data[x] < -data[y]) std::swap(x, y);
        data[x] += data[y];
        data[y] = x;
        num--;
        return true;
    }

    bool same(int x, int y) {
        assert(0 <= x && x < n);
        assert(0 <= y && y < n);
        return find(x) == find(y);
    }

    int size(int x) {
        assert(0 <= x && x < n);
        return -data[find(x)];
    }

    int count() const { return num; }

    std::vector<std::vector<int>> groups() {
        std::vector<std::vector<int>> res(n);
        for (int i = 0; i < n; i++) res[find(i)].emplace_back(i);
        res.erase(std::remove_if(res.begin(), res.end(), [&](const std::vector<int>& v) { return v.empty(); }));
        return res;
    }

    int operator[](int x) { return find(x); }

private:
    int n, num;
    // root node : -1 * component size
    // otherwise : parent
    std::vector<int> data;
};

/**
 * @brief Union Find (Disjoint Set Union)
 * @docs docs/datastructure/UnionFind.md
 */

struct TopologicalSort {
    std::vector<std::vector<int>> G;

    TopologicalSort(int n) : G(n), n(n), indeg(n, 0) {}

    void add_edge(int u, int v) {
        assert(0 <= u && u < n);
        assert(0 <= v && v < n);
        G[u].emplace_back(v);
        indeg[v]++;
    }

    std::vector<int> build() {
        std::queue<int> que;
        for (int i = 0; i < n; i++) {
            if (indeg[i] == 0) {
                que.emplace(i);
            }
        }
        std::vector<int> order;
        while (!que.empty()) {
            int v = que.front();
            que.pop();
            order.emplace_back(v);
            for (int& u : G[v]) {
                if (--indeg[u] == 0) {
                    que.emplace(u);
                }
            }
        }
        if (*std::max_element(indeg.begin(), indeg.end()) != 0) return {};
        return order;
    }

private:
    int n;
    std::vector<int> indeg;
};

/**
 * @brief Topological Sort
 * @docs docs/graph/TopologicalSort.md
 */

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N;
    cin >> N;
    vector<int> c(N);
    for (int& x : c) cin >> x;
    int M;
    cin >> M;
    vector<vector<int>> G(N);
    for (; M--;) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        G[a].emplace_back(b);
        G[b].emplace_back(a);
    }

    vector<vector<vector<int>>> adj(N);
    UnionFind UF(N);
    for (int i = 0; i < N; i++) {
        map<int, vector<int>> mp;
        mp[c[i]].emplace_back(i);
        for (int& j : G[i]) mp[c[j]].emplace_back(j);
        for (auto p : mp) {
            auto& v = p.second;
            adj[i].emplace_back(v);
            for (size_t j = 0; j + 1 < v.size(); j++) UF.merge(v[j], v[j + 1]);
        }
    }

    TopologicalSort TS(N);
    for (int i = 0; i < N; i++) {
        for (size_t j = 0; j + 1 < adj[i].size(); j++) {
            TS.add_edge(UF[adj[i][j][0]], UF[adj[i][j + 1][0]]);
        }
    }

    auto ord = TS.build();
    auto& g = TS.G;
    vector<int> dp(N, 1);
    for (int i = 0; i < N; i++) {
        int v = ord[i];
        for (int& u : g[v]) dp[u] = max(dp[u], dp[v] + 1);
    }

    ll ans = 0;
    for (int i = 0; i < N; i++) {
        if (UF[i] == i) {
            ans += 1LL * dp[i] * UF.size(i);
        }
    }
    cout << ans << '\n';
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 50816
final_rank: 8

code_snippet: #define LOCAL
#include <bits/stdc++.h>
using namespace std;
#pragma region Macros
typedef long long ll;
typedef __int128_t i128;
typedef unsigned int uint;
typedef unsigned long long ull;
#define ALL(x) (x).begin(), (x).end()

template <typename T> istream& operator>>(istream& is, vector<T>& v) {
    for (T& x : v) is >> x;
    return is;
}
template <typename T> ostream& operator<<(ostream& os, const vector<T>& v) {
    for (size_t i = 0; i < v.size(); i++) {
        os << v[i] << (i + 1 == v.size() ? "" : " ");
    }
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const unordered_map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const multiset<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const unordered_set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const deque<T>& v) {
    for (size_t i = 0; i < v.size(); i++) {
        os << v[i] << (i + 1 == v.size() ? "" : " ");
    }
    return os;
}
template <typename T, size_t N> ostream& operator<<(ostream& os, const array<T, N>& v) {
    for (size_t i = 0; i < N; i++) {
        os << v[i] << (i + 1 == N ? "" : " ");
    }
    return os;
}

template <int i, typename T> void print_tuple(ostream&, const T&) {}
template <int i, typename T, typename H, class... Args> void print_tuple(ostream& os, const T& t) {
    if (i) os << ',';
    os << get<i>(t);
    print_tuple<i + 1, T, Args...>(os, t);
}
template <typename... Args> ostream& operator<<(ostream& os, const tuple<Args...>& t) {
    os << '{';
    print_tuple<0, tuple<Args...>, Args...>(os, t);
    return os << '}';
}

void debug_out() { cerr << '\n'; }
template <class Head, class... Tail> void debug_out(Head&& head, Tail&&... tail) {
    cerr << head;
    if (sizeof...(Tail) > 0) cerr << ", ";
    debug_out(move(tail)...);
}
#ifdef LOCAL
#define debug(...)                                                                   \
    cerr << " ";                                                                     \
    cerr << #__VA_ARGS__ << " :[" << __LINE__ << ":" << __FUNCTION__ << "]" << '\n'; \
    cerr << " ";                                                                     \
    debug_out(__VA_ARGS__)
#else
#define debug(...) void(0)
#endif

template <typename T> T gcd(T x, T y) { return y != 0 ? gcd(y, x % y) : x; }
template <typename T> T lcm(T x, T y) { return x / gcd(x, y) * y; }

int topbit(signed t) { return t == 0 ? -1 : 31 - __builtin_clz(t); }
int topbit(long long t) { return t == 0 ? -1 : 63 - __builtin_clzll(t); }
int botbit(signed a) { return a == 0 ? 32 : __builtin_ctz(a); }
int botbit(long long a) { return a == 0 ? 64 : __builtin_ctzll(a); }
int popcount(signed t) { return __builtin_popcount(t); }
int popcount(long long t) { return __builtin_popcountll(t); }
bool ispow2(int i) { return i && (i & -i) == i; }
long long MSK(int n) { return (1LL << n) - 1; }

template <class T> T ceil(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <class T> T floor(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? x / y : (x - y + 1) / y);
}

template <class T1, class T2> inline bool chmin(T1& a, T2 b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T1, class T2> inline bool chmax(T1& a, T2 b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

template <typename T> void mkuni(vector<T>& v) {
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
}
template <typename T> int lwb(const vector<T>& v, const T& x) { return lower_bound(v.begin(), v.end(), x) - v.begin(); }
#pragma endregion

#include <algorithm>
#include <cassert>
#include <vector>

struct UnionFind {
    UnionFind(int n) : n(n), num(n), data(n, -1) {}

    int find(int x) {
        assert(0 <= x && x < n);
        return data[x] < 0 ? x : data[x] = find(data[x]);
    }

    bool merge(int x, int y) {
        assert(0 <= x && x < n);
        assert(0 <= y && y < n);
        if ((x = find(x)) == (y = find(y))) return false;
        if (-data[x] < -data[y]) std::swap(x, y);
        data[x] += data[y];
        data[y] = x;
        num--;
        return true;
    }

    bool same(int x, int y) {
        assert(0 <= x && x < n);
        assert(0 <= y && y < n);
        return find(x) == find(y);
    }

    int size(int x) {
        assert(0 <= x && x < n);
        return -data[find(x)];
    }

    int count() const { return num; }

    std::vector<std::vector<int>> groups() {
        std::vector<std::vector<int>> res(n);
        for (int i = 0; i < n; i++) res[find(i)].emplace_back(i);
        res.erase(std::remove_if(res.begin(), res.end(), [&](const std::vector<int>& v) { return v.empty(); }));
        return res;
    }

    int operator[](int x) { return find(x); }

private:
    int n, num;
    // root node : -1 * component size
    // otherwise : parent
    std::vector<int> data;
};

/**
 * @brief Union Find (Disjoint Set Union)
 * @docs docs/datastructure/UnionFind.md
 */

#include <algorithm>
#include <cassert>
#include <queue>
#include <vector>

struct TopologicalSort {
    std::vector<std::vector<int>> G;

    TopologicalSort(int n) : G(n), n(n), indeg(n, 0) {}

    void add_edge(int u, int v) {
        assert(0 <= u && u < n);
        assert(0 <= v && v < n);
        G[u].emplace_back(v);
        indeg[v]++;
    }

    std::vector<int> build() {
        std::queue<int> que;
        for (int i = 0; i < n; i++) {
            if (indeg[i] == 0) {
                que.emplace(i);
            }
        }
        std::vector<int> order;
        while (!que.empty()) {
            int v = que.front();
            que.pop();
            order.emplace_back(v);
            for (int& u : G[v]) {
                if (--indeg[u] == 0) {
                    que.emplace(u);
                }
            }
        }
        if (*std::max_element(indeg.begin(), indeg.end()) != 0) return {};
        return order;
    }

private:
    int n;
    std::vector<int> indeg;
};

/**
 * @brief Topological Sort
 * @docs docs/graph/TopologicalSort.md
 */

const int INF = 1e9;
const long long IINF = 1e18;
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const char dir[4] = {'D', 'R', 'U', 'L'};
const long long MOD = 1000000007;
// const long long MOD = 998244353;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N;
    cin >> N;
    vector<int> c(N);
    for (int& x : c) cin >> x;
    int M;
    cin >> M;
    vector<vector<int>> G(N);
    for (; M--;) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        G[a].emplace_back(b);
        G[b].emplace_back(a);
    }

    vector<vector<vector<int>>> adj(N);
    UnionFind UF(N);
    for (int i = 0; i < N; i++) {
        map<int, vector<int>> mp;
        mp[c[i]].emplace_back(i);
        for (int& j : G[i]) mp[c[j]].emplace_back(j);
        for (auto p : mp) {
            auto& v = p.second;
            adj[i].emplace_back(v);
            for (size_t j = 0; j + 1 < v.size(); j++) UF.merge(v[j], v[j + 1]);
        }
    }

    TopologicalSort TS(N);
    for (int i = 0; i < N; i++) {
        for (size_t j = 0; j + 1 < adj[i].size(); j++) {
            TS.add_edge(UF[adj[i][j][0]], UF[adj[i][j + 1][0]]);
        }
    }

    auto ord = TS.build();
    auto& g = TS.G;
    vector<int> dp(N, 1);
    for (int i = 0; i < N; i++) {
        int v = ord[i];
        for (int& u : g[v]) dp[u] = max(dp[u], dp[v] + 1);
    }

    ll ans = 0;
    for (int i = 0; i < N; i++) {
        if (UF[i] == i) {
            ans += 1LL * dp[i] * UF.size(i);
        }
    }
    cout << ans << '\n';
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 50704
final_rank: 7

code_snippet: #define LOCAL
#include <bits/stdc++.h>
using namespace std;
#pragma region Macros
typedef long long ll;
typedef __int128_t i128;
typedef unsigned int uint;
typedef unsigned long long ull;
#define ALL(x) (x).begin(), (x).end()

template <typename T> istream& operator>>(istream& is, vector<T>& v) {
    for (T& x : v) is >> x;
    return is;
}
template <typename T> ostream& operator<<(ostream& os, const vector<T>& v) {
    for (size_t i = 0; i < v.size(); i++) {
        os << v[i] << (i + 1 == v.size() ? "" : " ");
    }
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const unordered_map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const multiset<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const unordered_set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const deque<T>& v) {
    for (size_t i = 0; i < v.size(); i++) {
        os << v[i] << (i + 1 == v.size() ? "" : " ");
    }
    return os;
}
template <typename T, size_t N> ostream& operator<<(ostream& os, const array<T, N>& v) {
    for (size_t i = 0; i < N; i++) {
        os << v[i] << (i + 1 == N ? "" : " ");
    }
    return os;
}

template <int i, typename T> void print_tuple(ostream&, const T&) {}
template <int i, typename T, typename H, class... Args> void print_tuple(ostream& os, const T& t) {
    if (i) os << ',';
    os << get<i>(t);
    print_tuple<i + 1, T, Args...>(os, t);
}
template <typename... Args> ostream& operator<<(ostream& os, const tuple<Args...>& t) {
    os << '{';
    print_tuple<0, tuple<Args...>, Args...>(os, t);
    return os << '}';
}

void debug_out() { cerr << '\n'; }
template <class Head, class... Tail> void debug_out(Head&& head, Tail&&... tail) {
    cerr << head;
    if (sizeof...(Tail) > 0) cerr << ", ";
    debug_out(move(tail)...);
}
#ifdef LOCAL
#define debug(...)                                                                   \
    cerr << " ";                                                                     \
    cerr << #__VA_ARGS__ << " :[" << __LINE__ << ":" << __FUNCTION__ << "]" << '\n'; \
    cerr << " ";                                                                     \
    debug_out(__VA_ARGS__)
#else
#define debug(...) void(0)
#endif

template <typename T> T gcd(T x, T y) { return y != 0 ? gcd(y, x % y) : x; }
template <typename T> T lcm(T x, T y) { return x / gcd(x, y) * y; }

int topbit(signed t) { return t == 0 ? -1 : 31 - __builtin_clz(t); }
int topbit(long long t) { return t == 0 ? -1 : 63 - __builtin_clzll(t); }
int botbit(signed a) { return a == 0 ? 32 : __builtin_ctz(a); }
int botbit(long long a) { return a == 0 ? 64 : __builtin_ctzll(a); }
int popcount(signed t) { return __builtin_popcount(t); }
int popcount(long long t) { return __builtin_popcountll(t); }
bool ispow2(int i) { return i && (i & -i) == i; }
long long MSK(int n) { return (1LL << n) - 1; }

template <class T> T ceil(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <class T> T floor(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? x / y : (x - y + 1) / y);
}

template <class T1, class T2> inline bool chmin(T1& a, T2 b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T1, class T2> inline bool chmax(T1& a, T2 b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

template <typename T> void mkuni(vector<T>& v) {
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
}
template <typename T> int lwb(const vector<T>& v, const T& x) { return lower_bound(v.begin(), v.end(), x) - v.begin(); }
#pragma endregion

#include <algorithm>
#include <cassert>
#include <queue>
#include <vector>

struct TopologicalSort {
    std::vector<std::vector<int>> G;

    TopologicalSort(int n) : G(n), n(n), indeg(n, 0) {}

    void add_edge(int u, int v) {
        assert(0 <= u && u < n);
        assert(0 <= v && v < n);
        G[u].emplace_back(v);
        indeg[v]++;
    }

    std::vector<int> build() {
        std::queue<int> que;
        for (int i = 0; i < n; i++) {
            if (indeg[i] == 0) {
                que.emplace(i);
            }
        }
        std::vector<int> order;
        while (!que.empty()) {
            int v = que.front();
            que.pop();
            order.emplace_back(v);
            for (int& u : G[v]) {
                if (--indeg[u] == 0) {
                    que.emplace(u);
                }
            }
        }
        if (*std::max_element(indeg.begin(), indeg.end()) != 0) return {};
        return order;
    }

private:
    int n;
    std::vector<int> indeg;
};

/**
 * @brief Topological Sort
 * @docs docs/graph/TopologicalSort.md
 */

const int INF = 1e9;
const long long IINF = 1e18;
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const char dir[4] = {'D', 'R', 'U', 'L'};
const long long MOD = 1000000007;
// const long long MOD = 998244353;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N;
    cin >> N;
    vector<int> c(N);
    for (int& x : c) cin >> x;
    int M;
    cin >> M;
    vector<vector<int>> G(N);
    for (; M--;) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        G[a].emplace_back(b);
        G[b].emplace_back(a);
    }

    vector<vector<vector<int>>> adj(N);
    int n = N;
    for (int i = 0; i < N; i++) {
        map<int, vector<int>> mp;
        for (int& j : G[i]) mp[c[j]].emplace_back(j);
        if (mp.empty()) continue;
        n += mp.size() - 1;
        for (auto p : mp) adj[i].emplace_back(p.second);
    }

    TopologicalSort TS(n);
    for (int i = 0, cur = N; i < N; i++) {
        for (size_t j = 0; j + 1 < adj[i].size(); j++) {
            for (int& v : adj[i][j]) TS.add_edge(v, cur);
            for (int& v : adj[i][j + 1]) TS.add_edge(cur, v);
            cur++;
        }
    }
    for (int i = 0; i < N; i++) {
        for (int& j : G[i]) {
            if (c[i] < c[j]) {
                TS.add_edge(i, j);
            }
        }
    }

    auto ord = TS.build();
    auto& g = TS.G;
    vector<int> dp(n, 1);
    for (int i = 0; i < n; i++) {
        int v = ord[i];
        for (int& u : g[v]) {
            if (u < N)
                dp[u] = max(dp[u], dp[v] + 1);
            else
                dp[u] = max(dp[u], dp[v]);
        }
    }

    ll ans = 0;
    for (int i = 0; i < N; i++) ans += dp[i];
    cout << ans << '\n';
    return 0;
}
accuracy: 0.22580645161290322
time_ms: 160
memory_kb: 63204
final_rank: 15

code_snippet: #define LOCAL
#include <bits/stdc++.h>
using namespace std;
#pragma region Macros
typedef long long ll;
typedef __int128_t i128;
typedef unsigned int uint;
typedef unsigned long long ull;
#define ALL(x) (x).begin(), (x).end()

template <typename T> istream& operator>>(istream& is, vector<T>& v) {
    for (T& x : v) is >> x;
    return is;
}
template <typename T> ostream& operator<<(ostream& os, const vector<T>& v) {
    for (size_t i = 0; i < v.size(); i++) {
        os << v[i] << (i + 1 == v.size() ? "" : " ");
    }
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const unordered_map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const multiset<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const unordered_set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const deque<T>& v) {
    for (size_t i = 0; i < v.size(); i++) {
        os << v[i] << (i + 1 == v.size() ? "" : " ");
    }
    return os;
}
template <typename T, size_t N> ostream& operator<<(ostream& os, const array<T, N>& v) {
    for (size_t i = 0; i < N; i++) {
        os << v[i] << (i + 1 == N ? "" : " ");
    }
    return os;
}

template <int i, typename T> void print_tuple(ostream&, const T&) {}
template <int i, typename T, typename H, class... Args> void print_tuple(ostream& os, const T& t) {
    if (i) os << ',';
    os << get<i>(t);
    print_tuple<i + 1, T, Args...>(os, t);
}
template <typename... Args> ostream& operator<<(ostream& os, const tuple<Args...>& t) {
    os << '{';
    print_tuple<0, tuple<Args...>, Args...>(os, t);
    return os << '}';
}

void debug_out() { cerr << '\n'; }
template <class Head, class... Tail> void debug_out(Head&& head, Tail&&... tail) {
    cerr << head;
    if (sizeof...(Tail) > 0) cerr << ", ";
    debug_out(move(tail)...);
}
#ifdef LOCAL
#define debug(...)                                                                   \
    cerr << " ";                                                                     \
    cerr << #__VA_ARGS__ << " :[" << __LINE__ << ":" << __FUNCTION__ << "]" << '\n'; \
    cerr << " ";                                                                     \
    debug_out(__VA_ARGS__)
#else
#define debug(...) void(0)
#endif

template <typename T> T gcd(T x, T y) { return y != 0 ? gcd(y, x % y) : x; }
template <typename T> T lcm(T x, T y) { return x / gcd(x, y) * y; }

int topbit(signed t) { return t == 0 ? -1 : 31 - __builtin_clz(t); }
int topbit(long long t) { return t == 0 ? -1 : 63 - __builtin_clzll(t); }
int botbit(signed a) { return a == 0 ? 32 : __builtin_ctz(a); }
int botbit(long long a) { return a == 0 ? 64 : __builtin_ctzll(a); }
int popcount(signed t) { return __builtin_popcount(t); }
int popcount(long long t) { return __builtin_popcountll(t); }
bool ispow2(int i) { return i && (i & -i) == i; }
long long MSK(int n) { return (1LL << n) - 1; }

template <class T> T ceil(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <class T> T floor(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? x / y : (x - y + 1) / y);
}

template <class T1, class T2> inline bool chmin(T1& a, T2 b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T1, class T2> inline bool chmax(T1& a, T2 b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

template <typename T> void mkuni(vector<T>& v) {
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
}
template <typename T> int lwb(const vector<T>& v, const T& x) { return lower_bound(v.begin(), v.end(), x) - v.begin(); }
#pragma endregion

#include <algorithm>
#include <cassert>
#include <queue>
#include <vector>

struct TopologicalSort {
    std::vector<std::vector<int>> G;

    TopologicalSort(int n) : G(n), n(n), indeg(n, 0) {}

    void add_edge(int u, int v) {
        assert(0 <= u && u < n);
        assert(0 <= v && v < n);
        G[u].emplace_back(v);
        indeg[v]++;
    }

    std::vector<int> build() {
        std::queue<int> que;
        for (int i = 0; i < n; i++) {
            if (indeg[i] == 0) {
                que.emplace(i);
            }
        }
        std::vector<int> order;
        while (!que.empty()) {
            int v = que.front();
            que.pop();
            order.emplace_back(v);
            for (int& u : G[v]) {
                if (--indeg[u] == 0) {
                    que.emplace(u);
                }
            }
        }
        if (*std::max_element(indeg.begin(), indeg.end()) != 0) return {};
        return order;
    }

private:
    int n;
    std::vector<int> indeg;
};

/**
 * @brief Topological Sort
 * @docs docs/graph/TopologicalSort.md
 */

const int INF = 1e9;
const long long IINF = 1e18;
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const char dir[4] = {'D', 'R', 'U', 'L'};
const long long MOD = 1000000007;
// const long long MOD = 998244353;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N;
    cin >> N;
    vector<int> c(N);
    for (int& x : c) cin >> x;
    int M;
    cin >> M;
    vector<vector<int>> G(N);
    for (; M--;) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        G[a].emplace_back(b);
        G[b].emplace_back(a);
    }

    vector<vector<vector<int>>> adj(N);
    int n = N;
    for (int i = 0; i < N; i++) {
        map<int, vector<int>> mp;
        mp[c[i]].emplace_back(i);
        for (int& j : G[i]) mp[c[j]].emplace_back(j);
        n += mp.size() - 1;
        for (auto p : mp) adj[i].emplace_back(p.second);
    }

    TopologicalSort TS(n);
    for (int i = 0, cur = N; i < N; i++) {
        for (size_t j = 0; j + 1 < adj[i].size(); j++) {
            for (int& v : adj[i][j]) TS.add_edge(v, cur);
            for (int& v : adj[i][j + 1]) TS.add_edge(cur, v);
            cur++;
        }
    }

    auto ord = TS.build();
    auto& g = TS.G;
    vector<int> dp(n, 1);
    for (int i = 0; i < n; i++) {
        int v = ord[i];
        for (int& u : g[v]) {
            if (u < N)
                dp[u] = max(dp[u], dp[v] + 1);
            else
                dp[u] = max(dp[u], dp[v]);
        }
    }

    ll ans = 0;
    for (int i = 0; i < N; i++) ans += dp[i];
    cout << ans << '\n';
    return 0;
}
accuracy: 0.22580645161290322
time_ms: 190
memory_kb: 75132
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)

class UnionFind {
public:
    UnionFind() = default;
    explicit UnionFind(int n) : data(n, -1) {}

    int find(int x) {
        if (data[x] < 0) return x;
        return data[x] = find(data[x]);
    }

    void unite(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) return;
        if (data[x] > data[y]) std::swap(x, y);
        data[x] += data[y];
        data[y] = x;
    }

    bool same(int x, int y) {
        return find(x) == find(y);
    }

    int size(int x) {
        return -data[find(x)];
    }

private:
    std::vector<int> data;
};

std::vector<int> topological_sort(const std::vector<std::vector<int>>& G) {
    int V = G.size();
    std::vector<int> par_count(V);
    for (int u = 0; u < V; ++u) {
        for (int v : G[u]) ++par_count[v];
    }
    std::stack<int> start;
    for (int v = 0; v < V; ++v) {
        if (par_count[v] == 0) start.push(v);
    }

    std::vector<int> ret;
    while (!start.empty()) {
        int u = start.top();
        start.pop();
        ret.push_back(u);
        for (int v : G[u]) {
            --par_count[v];
            if (par_count[v] == 0) start.push(v);
        }
    }

    for (int c : par_count) {
        if (c > 0) return std::vector<int>();
    }
    return ret;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int N;
    cin>>N;
    vector<int> c(N);
    for (auto& x : c) cin >> x;
    int M;
    cin>>M;
    vector<vector<int>> G(N);
    rep(i,0,M) {
        int a, b;
        cin>>a>>b;
        --a,--b;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    UnionFind uf(N);
    rep(i, 0, N) {
        vector<pair<int, int>> vs;
        vs.push_back({c[i], i});
        for (int j : G[i]) {
            vs.push_back({c[j], j});
        }
        sort(vs.begin(), vs.end());
        rep(j, 0, vs.size()-1) {
            if (vs[j].first == vs[j+1].first) {
                uf.unite(vs[j].second, vs[j+1].second);
            }
        }
    }
    vector<vector<int>> H(N);
    rep(i, 0, N) {
        vector<pair<int, int>> vs;
        vs.push_back({c[i], i});
        for (int j : G[i]) {
            vs.push_back({c[j], j});
        }
        sort(vs.begin(), vs.end());
        rep(j, 0, vs.size()-1) {
            if (vs[j].first == vs[j+1].first) continue;
            H[uf.find(vs[j].second)].push_back(uf.find(vs[j+1].second));
        }
    }
    auto ord = topological_sort(H);
    vector<int> dist(N, 1);
    rep(i,0,N) {
        int v = ord[i];
        for (int u : H[v]) {
            dist[u] = max(dist[u], dist[v] + 1);
        }
    }
    ll ans = 0;
    rep(i, 0, N) {
        ans += dist[uf.find(i)];
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 70
memory_kb: 17176
final_rank: 1

code_snippet: #pragma GCC optimize("Ofast")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <cstdio>
#include <ctime>
#include <assert.h>
#include <chrono>
#include <random>
#include <numeric>
#include <set>
#include <deque>
#include <stack>
#include <sstream>
#include <utility>
#include <cstring>
using namespace std;
typedef long long int ll;
typedef unsigned long long ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}

struct UnionFind{
    vector<int> par,num;
    UnionFind(int n):par(n),num(n,1){
        iota(par.begin(),par.end(),0);  //include<numeric>
    }
    int find(int v){
        return (par[v]==v)?v:(par[v]=find(par[v]));
    }
    void unite(int u,int v){
        u=find(u),v=find(v);
        if(u==v)return;
        if(num[u]<num[v])swap(u,v);
        num[u]+=num[v];
        par[v]=u;
    }
    bool same(int u,int v){
        return find(u) == find(v);
    }
    int size(int v){
        return num[find(v)];
    }
};

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n; cin >> n;
    vector<int> c(n);
    for(int i=0;i<n;i++){
        cin >> c[i];
    }
    UnionFind uf(n);
    vector<vector<int>> g(n);
    int m; cin >> m;
    vector<int> x(m),y(m);
    for(int i=0;i<m;i++){
        cin >> x[i] >> y[i];
        x[i]--; y[i]--;
        g[x[i]].push_back(y[i]);
        g[y[i]].push_back(x[i]);
        if(c[x[i]] == c[y[i]]){
            uf.unite(x[i],y[i]);
        }
    }
    for(int i=0;i<n;i++){
        sort(g[i].begin(), g[i].end(),[&](auto j,auto k){
            return c[j] < c[k];
        });
        for(int j=0;j+1<g[i].size();j++){
            if(c[g[i][j]] == c[g[i][j+1]]){
                uf.unite(g[i][j], g[i][j+1]);
            }
        }
    }
    vector<vector<int>> dag(n);
    vector<int> deg(n);
    for(int i=0;i<m;i++){
        x[i]=uf.find(x[i]);
        y[i]=uf.find(y[i]);
        if(x[i]!=y[i]){
            if(c[x[i]]<c[y[i]]){
                dag[x[i]].push_back(y[i]);
                deg[y[i]]++;
            }
            else{
                dag[y[i]].push_back(x[i]);
                deg[x[i]]++;
            }
        }
    }
    vector<pair<int,int>> v;
    for(int i=0;i<n;i++){
        for(int j=0;j+1<g[i].size();j++){
            int a=uf.find(g[i][j]);
            int b=uf.find(g[i][j+1]);
            if(a!=b){
                if(c[a]<c[b]){
                    dag[a].push_back(b);
                    deg[b]++;
                }
                else{
                    dag[b].push_back(a);
                    deg[a]++;
                }
            }
        }
    }
    queue<int> q;
    for(int i=0;i<n;i++){
        if(uf.find(i) == i and deg[i] == 0){
            q.push(i);
        }
    }
    vector<ll> dp(n,1);
    while(q.size()){
        int s = q.front(); q.pop();
        // cout << s << " " << dp[s] << endl;
        for(int t:dag[s]){
            // cout << t << endl;
            dp[t] = max(dp[t], dp[s]+1);
            deg[t]--;
            if(deg[t] == 0)q.push(t);
        }
    }
    ll res = 0;
    for(int i=0;i<n;i++){
        if(uf.find(i) == i){
            res += dp[i] * (ll)uf.size(i);
        }
    }
    cout << res << endl;
}
accuracy: 1
time_ms: 70
memory_kb: 19884
final_rank: 2

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
//using namespace atcoder;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 25000000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-7;
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//const int mod = 1e9 + 7;
const int mod = 998244353;

struct UnionFind{
    vl p;
    vl rank;
    vl cnt;

    UnionFind(ll n){
        rank.resize(n,0);
        p.resize(n,0);
        cnt.resize(n,0);
        rep(i,n){
            p[i] = i;
            rank[i] = 0;
            cnt[i] = 1;
        }
    }

    ll find(ll x){
        if(x != p[x]) p[x] = find(p[x]);
        return p[x];
    }

    bool same(ll x, ll y){
        return find(x) == find(y);
    }

    void unite(ll x, ll y){
        x = find(x);
        y = find(y);
        if(x == y) return;
        if(rank[x] > rank[y]){
            p[y] = x;
            cnt[x] += cnt[y];
        }else{
            p[x] = y;
            cnt[y] += cnt[x];
            if(rank[x] == rank[y]) rank[y]++;
        }
    }

    ll size(ll x){
        return cnt[find(x)];
    }
};

int main(){
    int n; cin >> n;
    vl c(n); rep(i,n) cin >> c[i];
    vvl G(n), rev(n);
    int m; cin >> m;
    UnionFind uf(n);
    rep(i,m){
        int a,b; cin >> a >> b; a--; b--;
        if(a == b) continue;
        if(c[a] < c[b]) G[a].push_back(b), rev[b].push_back(a);
        else if(c[a] > c[b]) G[b].push_back(a), rev[a].push_back(b);
        else uf.unite(a,b);
    }
    vl x(n,-1);
    ll ans = 0;
    vl deg(n,0);
    rep(i,n) sort(all(G[i]), [&](ll a, ll b){return c[a] < c[b];});
    rep(i,n) sort(all(rev[i]), [&](ll a, ll b){return c[a] < c[b];});
    vvl g(n);
    rep(i,n){
        int m = G[i].size();
        if(m == 0) continue;
        rep(j,m-1){
            if(c[G[i][j]] == c[G[i][j+1]]) uf.unite(G[i][j], G[i][j+1]);
            else g[G[i][j]].push_back(G[i][j+1]); 
            g[i].push_back(G[i][j]);
        }
        g[i].push_back(G[i][m-1]);
    }
    rep(i,n){
        int m = rev[i].size();
        if(m == 0) continue;
        rep(j,m-1){
            if(c[rev[i][j]] == c[rev[i][j+1]]) uf.unite(rev[i][j], rev[i][j+1]);
            else g[rev[i][j]].push_back(rev[i][j+1]); 
        }
    }
    rep(i,n){
        if(uf.find(i) != i) for(auto v : g[i]) g[uf.find(i)].push_back(v);
    }
    rep(i,n){
        sort(all(g[i])); g[i].erase(unique(all(g[i])), g[i].end());
    }
    rep(i,n){
        if(uf.find(i) != i) g[i].clear();
        for(auto v : g[i]) deg[uf.find(v)]++;
    }
    queue<int> q;
    rep(i,n){
        if(uf.find(i) == i && deg[i] == 0) q.push(i), x[i] = 1;
    }
    while(!q.empty()){
        int u = q.front(); q.pop();
        for(auto v : g[u]){
            int nx = uf.find(v);
            deg[nx]--;
            if(deg[nx] == 0){
                q.push(nx);
                x[nx] = x[u] + 1;
            }
        }
    }
    rep(i,n) ans += x[uf.find(i)];
    cout << ans << endl;
}
accuracy: 1
time_ms: 130
memory_kb: 27244
final_rank: 6

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
//using namespace atcoder;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 25000000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-7;
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//const int mod = 1e9 + 7;
const int mod = 998244353;

int main(){
    int n; cin >> n;
    vpl v(n);
    rep(i,n){
        cin >> v[i].first;
        v[i].second = i;
    }
    sort(all(v));
    vvl G(n);
    int m; cin >> m;
    rep(i,m){
        int a,b; cin >> a >> b; a--; b--;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    vl x(n,-1), y(n,-1);
    ll ans = 0;
    vl ls;
    int pre = v[0].first;
    v.emplace_back(inf,-1);
    vl mxlist(n);
    rep(i,n+1){
        int mx = 0;
        if(pre < v[i].first){
            for(auto u : ls){
                for(auto to : G[v[u].second]){
                    chmax(mx, max(x[to],y[to]));
                }
                mxlist[u] = mx+1;
            }
            for(auto u : ls){
                x[v[u].second] = mxlist[u];
                ans += x[v[u].second];
                for(auto to : G[v[u].second]) chmax(y[to], x[v[u].second]);
            }
            ls.clear();
            pre = v[i].first;
        }
        ls.push_back(i);
    }
    cout << ans << endl;
}
accuracy: 0.12903225806451613
time_ms: 80
memory_kb: 13884
final_rank: 18