Problem: You are given an integer sequence of length N: A_1,A_2,...,A_N. Let us perform Q operations in order. The i-th operation is described by two integers X_i and Y_i. In this operation, we will choose one of the following two actions and perform it:

* Swap the values of A_{X_i} and A_{Y_i}
* Do nothing



There are 2^Q ways to perform these operations. Find the sum of the inversion numbers of the final sequences for all of these ways to perform operations, modulo 10^9+7.

Here, the inversion number of a sequence P_1,P_2,...,P_M is the number of pairs of integers (i,j) such that 1\leq i < j\leq M and P_i > P_j.

Constraints

* 1 \leq N \leq 3000
* 0 \leq Q \leq 3000
* 0 \leq A_i \leq 10^9(1\leq i\leq N)
* 1 \leq X_i,Y_i \leq N(1\leq i\leq Q)
* X_i\neq Y_i(1\leq i\leq Q)
* All values in input are integers.

Input

Input is given from Standard Input in the following format:


N Q
A_1
:
A_N
X_1 Y_1
:
X_Q Y_Q


Output

Print the sum of the inversion numbers of the final sequences, modulo 10^9+7.

Examples

Input

3 2
1
2
3
1 2
1 3


Output

6


Input

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


Output

36


Input

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


Output

425

Solution (in JAVA):

Solution:
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
public class Main {
	public static void main(String args[]) {
		FastScanner sc = new FastScanner(System.in);
		long mod = 1000000007;
		int n = sc.nextInt();
		int q = sc.nextInt();
		int[] a = new int[n];
		for(int i=0; i<n; i++) {
			a[i] = sc.nextInt();
		}
		long dp[][] = new long[n][n];
		for(int i=0; i<n; i++) {
			for(int j=0; j<n; j++) {
				if(a[i] > a[j])
					dp[i][j] = 1;
			}
		}
		long half = inverse(2,mod);

		for(int i=0; i<q; i++) {
			int x = sc.nextInt();
			int y = sc.nextInt();
			for(int j=0; j<n; j++) {
				if(j!=y-1 && j!=x-1) {
					dp[y-1][j] = dp[x-1][j] = (half * dp[x-1][j] % mod + half * dp[y-1][j] % mod)%mod;
					dp[j][x-1] = dp[j][y-1] = (half * dp[j][x-1] % mod + half * dp[j][y-1] % mod)%mod;
				}
				dp[y-1][x-1] = dp[x-1][y-1] = (half * dp[y-1][x-1] % mod + half * dp[x-1][y-1] % mod)%mod;
			}

		}

		long expectation = 0;
		for(int i=0; i<n; i++) {
			for(int j=i+1; j<n; j++) {
				expectation = (expectation + dp[i][j]) %mod;
			}
		}
		System.out.println(expectation*bin_exp(2,q,mod)%mod);
	}
	
	public static long bin_exp(long base, long exp, long mod) {
		if(exp == 0)
			return 1;
		return bin_exp(base*base%mod, exp/2, mod) * (exp%2 == 1? base : 1) % mod;
	}
	
	public static long inverse(long a, long mod) {
		return bin_exp(a,mod-2,mod);
	}
}

class FastScanner{
    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;
    
    public FastScanner(InputStream stream)
    {
        this.stream = stream;
    }
    
    int read()
    {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars){
            curChar = 0;
            try{
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }
    
    boolean isSpaceChar(int c)
    {
        return c==' '||c=='\n'||c=='\r'||c=='\t'||c==-1;
    }
    
    boolean isEndline(int c)
    {
        return c=='\n'||c=='\r'||c==-1;
    }
    
    int nextInt()
    {
        return Integer.parseInt(next());
    }
    
    long nextLong()
    {
        return Long.parseLong(next());
    }
    
    double nextDouble()
    {
        return Double.parseDouble(next());
    }
    
    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();
    }
    
    String nextLine(){
        int c = read();
        while (isEndline(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do{
            res.appendCodePoint(c);
            c = read();
        }while(!isEndline(c));
        return res.toString();
    }
}