#if defined(_USE_PCH_)
#include "pch.hpp"
#else
#include <bits/stdc++.h>
#endif
#define RNG(V_, A_, B_, ...) for(int V_=(A_), V_##_END=(B_) __VA_OPT__(,) __VA_ARGS__; V_<=V_##_END; V_++)
#define IRNG(V_, A_, B_, ...) for(int V_=(A_), V_##_END=(B_) __VA_OPT__(,) __VA_ARGS__; V_>=V_##_END; V_--)
#ifdef _WIN32
#define long int64_t
#endif
#define _UN using namespace
using namespace std;
typedef pair<int,int> pii;
const int MAXN=1e5+10,INF=0x3f3f3f3f;
int n,m,qn,C[MAXN]; bool bleaf[MAXN];
mt19937 rng;
struct _T{
    vector<int> G[MAXN]; set<pair<int,int>> Gs[MAXN]; map<int,int> colsz[MAXN];
    int dfn[MAXN],fa[MAXN],dfnc,siz[MAXN],dfns[MAXN],val1[MAXN];
    struct FhqTreap{
        struct{ int fa,ls,rs,sz,pri,mn,val,tag; } T[MAXN];
        void pushup(int u){
            T[u].sz=T[T[u].ls].sz+T[T[u].rs].sz;
            T[u].mn=min({T[T[u].ls].mn+T[T[u].ls].tag,T[T[u].rs].mn+T[T[u].rs].tag,T[u].val});
        }
        void pushdown(int u){
            if(T[u].ls) T[T[u].ls].tag+=T[u].tag;
            if(T[u].rs) T[T[u].rs].tag+=T[u].tag;
            T[u].tag=0;
        }
        int pos(int u){
            int c=1+T[T[u].ls].sz;
            for(int lst=u,u=T[u].fa; u; lst=u,u=T[u].fa){
                if(lst==T[u].rs) c+=1+T[T[u].ls].sz;
            }
            return c;
        }
        pair<int,int> split(int u,int c){
            if(!u) return {0,0};
            assert(0<=c&&c<=T[u].sz);
            if(!c) return {0,u};
            if(c==T[u].sz) return {u,0};
            pushdown(u);
            T[u].fa=0;
            if(c<=T[T[u].ls].sz){
                auto [v1,v2]=split(T[u].ls,c);
                T[u].ls=v2,T[v2].fa=u,pushup(u);
                return {v1,u};
            }else{
                c-=T[T[u].ls].sz+1;
                auto [v1,v2]=split(T[u].rs,c);
                T[u].rs=v1,T[v1].fa=u,pushup(u);
                return {u,v2};
            }
        }
        int merge(int u,int v){
            if(!u||!v) return u|v;
            if(T[u].pri<T[v].pri){
                pushdown(u);
                int w=merge(T[u].rs,v);
                T[u].rs=w,T[w].fa=u;
                pushup(u);
                return u;
            }else{
                pushdown(v);
                int w=merge(u,T[v].ls);
                T[v].ls=w,T[w].fa=u;
                pushup(v);
                return v;
            }
        }
        int build(int fa,int l,int r){
            if(l>r) return 0;
            int mid=(l+r)/2,u=dfns[mid];
            T[u]={fa,build(u,l,mid-1),build(u,mid+1,r),1,int(rng()),0,val1[u],0};
            pushup(u);
        }
        void add(int p,int len,int x){
            if(len==1){
                int u=p;
                T[u].tag+=x;
                if(T[u].ls) T[T[u].ls].tag-=x;
                if(T[u].rs) T[T[u].rs].tag-=x;
                while(u) pushup(u),u=T[u].fa;
            }
            int u,v,w;
            tie(u,v)=split(rt,pos(p)-1);
            tie(v,w)=split(v,len);
            T[v].tag+=x;
            rt=merge(merge(u,v),w);
            assert(fa[rt]==0);
        }
        void move(int p,int len,int q,int len1){
            int u,v,w;
            tie(u,v)=split(rt,pos(p)-1);
            tie(v,w)=split(v,len);
            rt=merge(u,w);
            tie(u,w)=split(rt,pos(q)+len1-1);
            rt=merge(merge(u,v),w);
            assert(fa[rt]==0);
        }
    } T;
    void dfs(int u,int fa_){
        dfn[u]=++dfnc,fa[u]=fa_,dfns[dfnc]=u;
        if(fa_) val1[u]=val1[fa_]+(C[u]!=C[fa_]);
        sort(G[u].begin(),G[u].end(),[](auto v1,auto v2){ return C[v1]<C[v2]; });
        for(int v:G[u]){
            if(v==fa_) continue;
            Gs[u].push_back({col[v],v});
            dfs(v,u);
            colsz[u][col[v]]+=siz[v];
            siz[u]+=siz[v];
        }
    }
    void init(){
        T.T[0].mn=INF;
        dfs(1,0);
        T.rt=T.build(0,1,n);
    }
    void upd(int u,int c){
        if(c==col[u]) return;
        auto do_=[u](int op){
            if(fa[u]&&col[fa[u]]!=col[u]) T.add(u,siz[u],op);
            if(Gs[u].size()) T.add(Gs[u].begin()->second,siz[u]-1,op);
            if(colsz[u][col[u]]) T.add(Gs[u].lower_bound({col[u],0})->second,colsz[u][col[u]],-op);
        };
        do_(-1);
        int oc=col[u];
        if(u!=1){
            auto it=Gs[fa[u]].insert({c,u}).first;
            if(it==Gs[fa[u]].begin()) T.move(u,siz[u],fa[u],1);
            else{
                int v=(--it)->second;
                if(v!=u) T.move(u,siz[u],v,siz[v]);
            }
            Gs[fa[u]].erase(pair<int,int>{oc,u});
            colsz[fa[u]][oc]-=siz[u],colsz[fa[u]][c]+=siz[u];
        }
        col[u]=c;
        do_(1);
    }
    int qry(){ return T.T[rt].val+T.T[rt].tag; }
} T1,T2;
vector<int> G[MAXN]; pii E[MAXN];
bool vis[MAXN],instk[MAXN],done;
int fa[MAXN];
void dfs(int u,int fa_){
    if(done) return;
    fa[u]=fa_,vis[u]=1,instk[u]=1;
    for(int v:G[u]){
        if(v==fa_) continue;
        if(vis[v]){
            for(int w:G[v]){
                if(w!=u&&w!=fa[v]&&instk[w]){
                    RNG(i,1,m){
                        auto [p,q]=E[i];
                        if(!(p==min(u,v)&&q==max(u,v))) T1.G[p].push_back(q),T1.G[q].push_back(p);
                    }
                    RNG(i,1,m){
                        auto [p,q]=E[i];
                        if(!(p==min(v,w)&&q==max(v,w))) T2.G[p].push_back(q),T2.G[q].push_back(p);
                    }
                    done=1;
                    return;
                }
            }
            assert(0);
        }
        if(done) return;
    }
    instk[u]=0;
}
int main(){
#if defined(_LOCAL_)
    freopen("in","r",stdin);
//  freopen("out","w",stdout);
//  freopen("/dev/null","w",stderr);
#else
    freopen("tree.in","r",stdin);
    freopen("tree.out","w",stdout);
#endif
    { int _; cin>>n>>m>>qn>>_; }
    RNG(u,1,n) cin>>C[u];
    RNG(i,1,m,u,v) cin>>u>>v,G[u].push_back(v),G[v].push_back(u),E[i]={min(u,v),max(u,v)};
    RNG(u,1,n) bleaf[u]=(G[u].size()==1)
    if(m==n-1){
        copy_n(G+1,n,T1.G+1);
        T1.init();
    }else{
        dfs(1,0); assert(done);
        T1.init(),T2.init();
    }
}