// O(N + M)解法 #include using namespace std; #define rep(i,a,b) for(int i = a; i < b; i ++ ) #define all(x) x.begin(),x.end() const int INF = 1<<30; using ll = long long; #define chmin(a,b) a = min(a,b) #define chmax(a,b) a = max(a,b) int main() { int N, M, X, K; cin >> N >> M >> X >> K; vector A(N); rep(i,0,N) cin >> A[i]; vector plus(N, INF), minus(N, 0); vector> G(2*N); auto add_edge = [&G](int i, int j) -> void { G[i].push_back(j); G[j].push_back(i); }; rep(i,0,M) { int u, v; cin >> u >> v; u -- , v -- ; if (A[u] > A[v]) swap(u,v); if (A[v] - A[u] <= X) add_edge(u, v + N); chmin(plus[u], A[v]); chmax(minus[v], A[u]); } rep(i,0,N) if (K == 2 || plus[i] - minus[i] <= X) add_edge(i, i + N); //DFSで色付ける vector col(2*N,-1); auto dfs = [&](auto&&self, int v, int c) -> void { if (col[v] == -1) col[v] = c; else return; for (auto x: G[v]) self(self, x, c); }; rep(i,0,2*N) dfs(dfs, i, i); ll ans = 0; vector cnt_col(2*N, 0); rep(i,0,N) if (col[i] != col[i+N]) cnt_col[col[i]] ++ ; rep(i,N,2*N) cnt_col[col[i]] ++ ; for (auto x: cnt_col) ans += x * (x - 1); // 複数のグループに含まれるやつについて vector> tr(2*N); rep(i,0,N) { if (col[i] < col[i+N]) tr[col[i]].push_back(col[i+N]); if (col[i] > col[i+N]) tr[col[i+N]].push_back(col[i]); } vector C(2*N, 0); //カウント用のやつ for (auto t: tr) { for (auto x: t) { ans -= C[x]; C[x] ++ ; } for (auto x: t) C[x] -- ; } cout << ans << endl; }