You've got an undirected graph, consisting of n vertices and m edges. We will consider the graph's vertices numbered with integers from 1 to n. Each vertex of the graph has a color. The color of the i-th vertex is an integer ci.

Let's consider all vertices of the graph, that are painted some color k. Let's denote a set of such as V(k). Let's denote the value of the neighbouring color diversity for color k as the cardinality of the set Q(k) = {cu : cu ≠ k and there is vertex v belonging to set V(k) such that nodes v and u are connected by an edge of the graph}.

Your task is to find such color k, which makes the cardinality of set Q(k) maximum. In other words, you want to find the color that has the most diverse neighbours. Please note, that you want to find such color k, that the graph has at least one vertex with such color.

Input

The first line contains two space-separated integers n, m (1 ≤ n, m ≤ 105) — the number of vertices end edges of the graph, correspondingly. The second line contains a sequence of integers c1, c2, ..., cn (1 ≤ ci ≤ 105) — the colors of the graph vertices. The numbers on the line are separated by spaces.

Next m lines contain the description of the edges: the i-th line contains two space-separated integers ai, bi (1 ≤ ai, bi ≤ n; ai ≠ bi) — the numbers of the vertices, connected by the i-th edge. 

It is guaranteed that the given graph has no self-loops or multiple edges.

Output

Print the number of the color which has the set of neighbours with the maximum cardinality. It there are multiple optimal colors, print the color with the minimum number. Please note, that you want to find such color, that the graph has at least one vertex with such color.

Examples

Input

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


Output

3


Input

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


Output

2
import java.util.*;
import java.io.*;
public class Solution
{
       
       public static class Suffix implements Comparable<Suffix>
    {
        int index;
        int rank;
        int next;
 
        public Suffix(int ind, int r, int nr) 
        {
            index = ind;
            rank = r;
            next = nr;
        }
         
        // A comparison function used by sort() 
        // to compare two suffixes.
        // Compares two pairs, returns 1
        // if first pair is smaller
        public int compareTo(Suffix s) 
        {
            if (rank != s.rank) return Integer.compare(rank, s.rank);
            return Integer.compare(next, s.next);
        }
    }
    
    
       static class Reader 
    { 
        final private int BUFFER_SIZE = 1 << 16; 
        private DataInputStream din; 
        private byte[] buffer; 
        private int bufferPointer, bytesRead; 
  
        public Reader() 
        { 
            din = new DataInputStream(System.in); 
            buffer = new byte[BUFFER_SIZE]; 
            bufferPointer = bytesRead = 0; 
        } 
  
        public Reader(String file_name) throws IOException 
        { 
            din = new DataInputStream(new FileInputStream(file_name)); 
            buffer = new byte[BUFFER_SIZE]; 
            bufferPointer = bytesRead = 0; 
        } 
  
        public String readLine() throws IOException 
        { 
            byte[] buf = new byte[64]; // line length 
            int cnt = 0, c; 
            while ((c = read()) != -1) 
            { 
                if (c == '\n') 
                    break; 
                buf[cnt++] = (byte) c; 
            } 
            return new String(buf, 0, cnt); 
        } 
  
        public int nextInt() throws IOException 
        { 
            int ret = 0; 
            byte c = read(); 
            while (c <= ' ') 
                c = read(); 
            boolean neg = (c == '-'); 
            if (neg) 
                c = read(); 
            do
            { 
                ret = ret * 10 + c - '0'; 
            }  while ((c = read()) >= '0' && c <= '9'); 
  
            if (neg) 
                return -ret; 
            return ret; 
        } 
  
        public long nextLong() throws IOException 
        { 
            long ret = 0; 
            byte c = read(); 
            while (c <= ' ') 
                c = read(); 
            boolean neg = (c == '-'); 
            if (neg) 
                c = read(); 
            do { 
                ret = ret * 10 + c - '0'; 
            } 
            while ((c = read()) >= '0' && c <= '9'); 
            if (neg) 
                return -ret; 
            return ret; 
        } 
  
        public double nextDouble() throws IOException 
        { 
            double ret = 0, div = 1; 
            byte c = read(); 
            while (c <= ' ') 
                c = read(); 
            boolean neg = (c == '-'); 
            if (neg) 
                c = read(); 
  
            do { 
                ret = ret * 10 + c - '0'; 
            } 
            while ((c = read()) >= '0' && c <= '9'); 
  
            if (c == '.') 
            { 
                while ((c = read()) >= '0' && c <= '9') 
                { 
                    ret += (c - '0') / (div *= 10); 
                } 
            } 
  
            if (neg) 
                return -ret; 
            return ret; 
        } 
  
        private void fillBuffer() throws IOException 
        { 
            bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE); 
            if (bytesRead == -1) 
                buffer[0] = -1; 
        } 
  
        private byte read() throws IOException 
        { 
            if (bufferPointer == bytesRead) 
                fillBuffer(); 
            return buffer[bufferPointer++]; 
        } 
  
        public void close() throws IOException 
        { 
            if (din == null) 
                return; 
            din.close(); 
        } 
    }
    static int getMid(int s, int e)
    {
        return s + (e - s) / 2;
    }
 
    /*
    * A recursive function to get the sum
    of values in given range of the array.
    * The following are parameters 
      for this function.
    *
    * st -> Pointer to segment tree
    * node -> Index of current node in
    *         the segment tree.
    * ss & se -> Starting and ending indexes
    *         of the segment represented
    *         by current node, i.e., st[node]
    * l & r -> Starting and ending indexes
    *         of range query
    */
    static int MaxUtil(int[] st, int ss, 
                       int se, int l,
                       int r, int node)
    {
 
        // If segment of this node is completely
        // part of given range, then return
        // the max of segment
        if (l <= ss && r >= se)
            return st[node];
 
        // If segment of this node does not
        // belong to given range
        if (se < l || ss > r)
            return -1;
 
        // If segment of this node is partially
        // the part of given range
        int mid = getMid(ss, se);
 
        return Math.max(
            MaxUtil(st, ss, mid, l, r,
                     2 * node + 1),
            MaxUtil(st, mid + 1, se, l, r,
                    2 * node + 2));
    }
 
    /*
    * A recursive function to update the
    nodes which have the given index in their
    * range. The following are parameters
    st, ss and se are same as defined above
    * index -> index of the element to be updated.
    */
    static void updateValue(int arr[], int[] 
                            st, int ss,
                            int se, int index, 
                            int value,
                            int node)
    {
        if (index < ss || index > se) {
            System.out.println("Invalid Input");
            return;
        }
 
        if (ss == se) {
 
            // update value in array and in
            // segment tree
            arr[index] = value;
            st[node] = value;
        }
        else {
            int mid = getMid(ss, se);
 
            if (index >= ss && index <= mid)
                updateValue(arr, st, ss, mid, 
                            index, value,
                            2 * node + 1);
            else
                updateValue(arr, st, mid + 1, se, index,
                            value, 2 * node + 2);
 
            st[node] = Math.max(st[2 * node + 1],
                                st[2 * node + 2]);
        }
        return;
    }
 
    // Return max of elements in range from
    // index l (query start) to r (query end).
    static int getMax(int[] st, int n, int l, int r)
    {
 
        // Check for erroneous input values
        if (l < 0 || r > n - 1 || l > r) {
            System.out.printf("Invalid Input\n");
            return -1;
        }
 
        return MaxUtil(st, 0, n - 1, l, r, 0);
    }
 
    // A recursive function that constructs Segment
    // Tree for array[ss..se]. si is index of
    // current node in segment tree st
    static int constructSTUtil(int arr[],
                               int ss, int se,
                               int[] st, int si)
    {
 
        // If there is one element in array, store
        // it in current node of segment tree and return
        if (ss == se) {
            st[si] = arr[ss];
            return arr[ss];
        }
 
        // If there are more than one elements, then
        // recur for left and right subtrees and
        // store the max of values in this node
        int mid = getMid(ss, se);
 
        st[si] = Math.max(
            constructSTUtil(arr, ss, mid,
                            st, si * 2 + 1),
            constructSTUtil(arr, mid + 1,
                            se, st,
                            si * 2 + 2));
 
        return st[si];
    }
 
    /*
    * Function to construct segment tree from
    given array. This function allocates
    * memory for segment tree.
    */
    static int[] constructST(int arr[], int n)
    {
 
        // Height of segment tree
        int x = (int)Math.ceil(Math.log(n) / Math.log(2));
 
        // Maximum size of segment tree
        int max_size = 2 * (int)Math.pow(2, x) - 1;
 
        // Allocate memory
        int[] st = new int[max_size];
 
        // Fill the allocated memory st
        constructSTUtil(arr, 0, n - 1, st, 0);
 
        // Return the constructed segment tree
        return st;
    }
    
    public static int[] suffixArray(String s) 
    {
        int n = s.length();
        Suffix[] su = new Suffix[n];
         
        // Store suffixes and their indexes in 
        // an array of classes. The class is needed 
        // to sort the suffixes alphabatically and
        // maintain their old indexes while sorting 
        for (int i = 0; i < n; i++) 
        {
            su[i] = new Suffix(i, s.charAt(i) - '$', 0);
        }
        for (int i = 0; i < n; i++) 
            su[i].next = (i + 1 < n ? su[i + 1].rank : -1);
 
        // Sort the suffixes using the comparison function 
        // defined above. 
        Arrays.sort(su);
 
        // At this point, all suffixes are sorted 
        // according to first 2 characters. 
        // Let us sort suffixes according to first 4 
        // characters, then first 8 and so on 
        int[] ind = new int[n];
         
        // This array is needed to get the index in suffixes[] 
        // from original index. This mapping is needed to get 
        // next suffix. 
        for (int length = 4; length < 2 * n; length <<= 1) 
        {
             
            // Assigning rank and index values to first suffix 
            int rank = 0, prev = su[0].rank;
            su[0].rank = rank;
            ind[su[0].index] = 0;
            for (int i = 1; i < n; i++)
            {
                // If first rank and next ranks are same as 
                // that of previous suffix in array, 
                // assign the same new rank to this suffix 
                if (su[i].rank == prev &&
                    su[i].next == su[i - 1].next)
                {
                    prev = su[i].rank;
                    su[i].rank = rank;
                } 
                else
                { 
                    // Otherwise increment rank and assign 
                    prev = su[i].rank;
                    su[i].rank = ++rank;
                }
                ind[su[i].index] = i;
            }
             
            // Assign next rank to every suffix 
            for (int i = 0; i < n; i++) 
            {
                int nextP = su[i].index + length / 2;
                su[i].next = nextP < n ? 
                   su[ind[nextP]].rank : -1;
            }
             
            // Sort the suffixes according 
            // to first k characters 
            Arrays.sort(su);
        }
 
        // Store indexes of all sorted 
        // suffixes in the suffix array 
        int[] suf = new int[n];
         
        for (int i = 0; i < n; i++) 
            suf[i] = su[i].index;
 
        // Return the suffix array 
        return suf;
    }
    
    static boolean present(String s , String pat , int len)
    {
           long p1 = 31 , p2 = 37;
           long mod1 = 1000000007 , mod2 = 1000000009;
           
           long shash1 = 0 , pathash1 = 0 , shash2 = 0 , pathash2 = 0;
           long curr1 = 1 , curr2 = 1;
           for(int i = 0 ; i < len ; i++)
           {
                  shash1 = shash1*p1+s.charAt(i)-'a'+1;
                  pathash1 = pathash1*p1+pat.charAt(i)-'a'+1;
                  if(i != pat.length()-1)
                  curr1 = curr1*p1;
                  
                  shash1 %= mod1;
                  pathash1 %= mod1;
                  curr1 %= mod1;
                  
                  
                   shash2 = shash2*p2+s.charAt(i)-'a'+1;
                  pathash2 = pathash2*p2+pat.charAt(i)-'a'+1;
                  if(i != pat.length()-1)
                  curr2 = curr2*p2;
                  
                  shash2 %= mod2;
                  pathash2 %= mod2;
                  curr2 %= mod2;
           }
           
           for(int i = 0 ; i < s.length() ; i++)
           {
                 if(pathash1 == shash1 && pathash2 == shash2)
                 return true;
                 
                 if(i+len >= s.length())
                 break;
                 
                 shash1 -= (long)(s.charAt(i)-'a'+1)*curr1%mod1;
                 shash1 = (shash1+mod1)%mod1;
                 shash1 = shash1*p1%mod1;
                 shash1 += s.charAt(i+len)-'a'+1;
                 shash1 %= mod1;
                 
                 
                 shash2 -= (long)(s.charAt(i)-'a'+1)*curr2%mod2;
                 shash2 = (shash2+mod2)%mod2;
                 shash2 = shash2*p2%mod2;
                 shash2 += s.charAt(i+len)-'a'+1;
                 shash2 %= mod2;
           }
           
           return false;
    }
    
   public static void main(String []args)
   {
       Scanner sc = new Scanner(System.in);
       int n = sc.nextInt();
       int m = sc.nextInt();
       
       
       int cc[] = new int[n];
       for(int i = 0 ; i < n ; i++)
       {
              cc[i] = sc.nextInt();
       }
      
       HashMap<Integer,Integer> c[] = new HashMap[100001];
       for(int i = 1 ; i <= 100000 ; i++)
       {
              c[i] = new HashMap<Integer,Integer>();
       }
       
       for(int i = 0 ; i < m ; i++)
       {
              int x = sc.nextInt()-1;
              int y = sc.nextInt()-1;
             if(cc[x] != cc[y])
             {
                  c[cc[x]].put(cc[y],1);
                  c[cc[y]].put(cc[x],1);
             }
       }
       boolean visited[] = new boolean[n];
       
      
       
       int mx = 0 , idx = 0;
       for(int i = 1 ; i <= 100000 ; i++)
       {
              if(c[i].size() > mx)
              {
                     mx = c[i].size();
                     idx = i;
              }
       }
       //System.out.println(c[1] + " " + c[3]);
      // System.out.println(idx);
      
      if(mx == 0)
      {
             int mn = 100000;
           for(int i = 0 ; i < n ; i++)
           {
                  mn = Math.min(mn,cc[i]);
           }
           System.out.println(mn);
      }
      
      else
      System.out.println(idx);
   }
}