Alex decided to go on a touristic trip over the country.

For simplicity let's assume that the country has n cities and m bidirectional roads connecting them. Alex lives in city s and initially located in it. To compare different cities Alex assigned each city a score w_i which is as high as interesting city seems to Alex.

Alex believes that his trip will be interesting only if he will not use any road twice in a row. That is if Alex came to city v from city u, he may choose as the next city in the trip any city connected with v by the road, except for the city u.

Your task is to help Alex plan his city in a way that maximizes total score over all cities he visited. Note that for each city its score is counted at most once, even if Alex been there several times during his trip.

Input

First line of input contains two integers n and m, (1 ≤ n ≤ 2 ⋅ 10^5, 0 ≤ m ≤ 2 ⋅ 10^5) which are numbers of cities and roads in the country.

Second line contains n integers w_1, w_2, …, w_n (0 ≤ w_i ≤ 10^9) which are scores of all cities.

The following m lines contain description of the roads. Each of these m lines contains two integers u and v (1 ≤ u, v ≤ n) which are cities connected by this road.

It is guaranteed that there is at most one direct road between any two cities, no city is connected to itself by the road and, finally, it is possible to go from any city to any other one using only roads.

The last line contains single integer s (1 ≤ s ≤ n), which is the number of the initial city.

Output

Output single integer which is the maximum possible sum of scores of visited cities.

Examples

Input


5 7
2 2 8 6 9
1 2
1 3
2 4
3 2
4 5
2 5
1 5
2


Output


27


Input


10 12
1 7 1 9 3 3 6 30 1 10
1 2
1 3
3 5
5 7
2 3
5 4
6 9
4 6
3 7
6 8
9 4
9 10
6


Output


61
// package CodeForces;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.LinkedList;

public class CwD_Graph_J {

	// Convert to a tree and than solve the problem
	
	public static LinkedList<Integer>[] g;
	public static LinkedList<Integer>[] tree;
	public static long ans = -1;
	public static long[] updated_values;
	
	public static void dfs(int current, int parent, long sum) {
		for(Integer x : tree[current]) {
			if(x != parent) {
				dfs(x, current, sum + updated_values[current]);
			}
		}
		ans = Math.max(sum + updated_values[current], ans);
	}
	
	public static long sum_till_root = 0;
	
	public static boolean dfs2(int current, int parent, long sum) {
		if(current == 0) {
			sum_till_root = sum + updated_values[current];
			updated_values[current] = 0;
			return true;
		}
		for(Integer x : tree[current]) {
			if(x != parent) {
				if(dfs2(x, current, sum + updated_values[current])) {
					updated_values[current] = 0;
					return true;
				}
			}
		}
		return false;
	}
	
	public static void solve() {
		int n = s.nextInt();
		int m = s.nextInt();
		long[] values = s.nextLongArray(n);
		g = new LinkedList[n];
		for(int i = 0; i < n; i++) {
			g[i] = new LinkedList<>();
		}
		int[] degree = new int[n];
		for(int i = 0; i < m; i++) {
			int u = s.nextInt() - 1;
			int v = s.nextInt() - 1;
			g[u].add(v);
			g[v].add(u);
			degree[u]++;
			degree[v]++;	
		}
		int start = s.nextInt() - 1;
		if(m == n - 1) {
			// already g is a tree 
			// solve the problem directly here
			tree = g;
			updated_values = values;
			dfs(start, start, 0);
			out.println(ans);
			return;
		}
		boolean[] treeNodes = new boolean[n];
		LinkedList<Integer> q = new LinkedList<Integer>();
		for(int i = 0; i < n; i++) {
			if(degree[i] == 1) {
				q.add(i);
			}
		}
		while(!q.isEmpty()) {
			int top = q.removeFirst();
			treeNodes[top] = true;
			for(Integer x : g[top]) {
				if(!treeNodes[x]) {
					degree[x]--;
					if(degree[x] <= 1) {
						q.add(x);
						treeNodes[x] = true;
					}
				}
			}
		}
		HashMap<Integer, Integer> grTOtr = new HashMap<>();
		int ptr = 1; // 0th node is for the root
		for(int i = 0; i < n; i++) {
			if(treeNodes[i]) {
				grTOtr.put(i, ptr);
				ptr++;
			}else {
				grTOtr.put(i, 0);
			}
		}
		updated_values = new long[ptr];
		for(int i = 0; i < n; i++) {
			int val = grTOtr.get(i);
			updated_values[val] += values[i];
		}
		start = grTOtr.get(start);
		tree = new LinkedList[ptr];
		for(int i = 0; i < ptr; i++) {
			tree[i] = new LinkedList<Integer>();
		}
		for(int i = 0; i < n; i++) {
			int v = grTOtr.get(i);
			for(Integer x : g[i]) {
				int u = grTOtr.get(x);
				if(u != v) {
					tree[v].add(u);
				}
			}
		}
		// solve the problem for a tree with root as start
		// this is the case when i'm already the root
		if(start == 0) dfs(start, start, 0);
		else {
			// make path till root as zero and then apply above algorithm again and add answer till root
			dfs2(start, start, 0);
			dfs(start, start, 0);
			out.println(ans + sum_till_root);
			return;
		}
		out.println(ans);
	}

	public static void main(String[] args) {
		new Thread(null, null, "Thread", 1 << 27) {
			public void run() {
				try {
					out = new PrintWriter(new BufferedOutputStream(System.out));
					s = new FastReader(System.in);
					solve();
					out.close();
				} catch (Exception e) {
					e.printStackTrace();
					System.exit(1);
				}
			}
		}.start();
	}

	public static PrintWriter out;
	public static FastReader s;

	public static class FastReader {

		private InputStream stream;
		private byte[] buf = new byte[4096];
		private int curChar, snumChars;

		public FastReader(InputStream stream) {
			this.stream = stream;
		}

		public int read() {
			if (snumChars == -1) {
				throw new InputMismatchException();
			}
			if (curChar >= snumChars) {
				curChar = 0;
				try {
					snumChars = stream.read(buf);
				} catch (IOException E) {
					throw new InputMismatchException();
				}
			}
			if (snumChars <= 0) {
				return -1;
			}
			return buf[curChar++];
		}

		public int nextInt() {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			int number = 0;
			do {
				number *= 10;
				number += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			return number * sgn;
		}

		public long nextLong() {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			long sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			long number = 0;
			do {
				number *= 10L;
				number += (long) (c - '0');
				c = read();
			} while (!isSpaceChar(c));
			return number * sgn;
		}

		public int[] nextIntArray(int n) {
			int[] arr = new int[n];
			for (int i = 0; i < n; i++) {
				arr[i] = this.nextInt();
			}
			return arr;
		}

		public long[] nextLongArray(int n) {
			long[] arr = new long[n];
			for (int i = 0; i < n; i++) {
				arr[i] = this.nextLong();
			}
			return arr;
		}

		public String next() {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine() {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isEndofLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public boolean isEndofLine(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

	}

	
}
