Seryozha conducts a course dedicated to building a map of heights of Stepanovo recreation center. He laid a rectangle grid of size n × m cells on a map (rows of grid are numbered from 1 to n from north to south, and columns are numbered from 1 to m from west to east). After that he measured the average height of each cell above Rybinsk sea level and obtained a matrix of heights of size n × m. The cell (i, j) lies on the intersection of the i-th row and the j-th column and has height h_{i, j}. 

Seryozha is going to look at the result of his work in the browser. The screen of Seryozha's laptop can fit a subrectangle of size a × b of matrix of heights (1 ≤ a ≤ n, 1 ≤ b ≤ m). Seryozha tries to decide how the weather can affect the recreation center — for example, if it rains, where all the rainwater will gather. To do so, he is going to find the cell having minimum height among all cells that are shown on the screen of his laptop.

Help Seryozha to calculate the sum of heights of such cells for all possible subrectangles he can see on his screen. In other words, you have to calculate the sum of minimum heights in submatrices of size a × b with top left corners in (i, j) over all 1 ≤ i ≤ n - a + 1 and 1 ≤ j ≤ m - b + 1.

Consider the sequence g_i = (g_{i - 1} ⋅ x + y) mod z. You are given integers g_0, x, y and z. By miraculous coincidence, h_{i, j} = g_{(i - 1) ⋅ m + j - 1} ((i - 1) ⋅ m + j - 1 is the index).

Input

The first line of the input contains four integers n, m, a and b (1 ≤ n, m ≤ 3 000, 1 ≤ a ≤ n, 1 ≤ b ≤ m) — the number of rows and columns in the matrix Seryozha has, and the number of rows and columns that can be shown on the screen of the laptop, respectively.

The second line of the input contains four integers g_0, x, y and z (0 ≤ g_0, x, y < z ≤ 10^9).

Output

Print a single integer — the answer to the problem.

Example

Input


3 4 2 1
1 2 3 59


Output


111

Note

The matrix from the first example: 

<image>
import java.io.*; 
import java.math.*;
import java.util.*;
import java.awt.Point;
 
public class Main {
	//static final long MOD = 998244353;
	static final long MOD = 1000000007;
	static final int INF = 1000000007;
	
	public static void main(String[] args) {
		long t1 = System.currentTimeMillis();
		FastScanner sc = new FastScanner();
		int N = sc.ni();
		int M = sc.ni();
		int A = sc.ni();
		int B = sc.ni();
		long G = sc.nl();
		long X = sc.nl();
		long Y = sc.nl();
		long Z = sc.nl();
		int[][] nums = new int[N][M];
		for (int row = 0; row < N; row++) {
			for (int col = 0; col < M; col++) {
				if (row==0&&col==0) {
					nums[0][0] = (int)G;
				} else {
					G = (G*X+Y)%Z;
					nums[row][col] = (int)G;
				}
			}
		}
		
		int[][] rowMins = new int[N][M-B+1];
		for (int i = 0; i < N; i++) {
			MinQueue q = new MinQueue();
			for (int j = 0; j < B; j++)
				q.add(nums[i][j]);
			rowMins[i][0] = q.queryMin();
			for (int j = B; j < M; j++) {
				q.remove();
				q.add(nums[i][j]);
				rowMins[i][j-B+1] = q.queryMin();
			}
		}
		
		int[][] colMins = new int[N-A+1][M-B+1];
		for (int j = 0; j < M-B+1; j++) {
			MinQueue q = new MinQueue();
			for (int i = 0; i < A; i++)
				q.add(rowMins[i][j]);
			colMins[0][j] = q.queryMin();
			for (int i = A; i < N; i++) {
				q.remove();
				q.add(rowMins[i][j]);
				colMins[i-A+1][j] = q.queryMin();
			}
		}
		
		long ans = 0;
		for (int i = 0; i < N-A+1; i++) {
			for (int j = 0; j < M-B+1; j++) {
				ans += colMins[i][j];
			}
		}
		System.out.println(ans);
 	}
	
	static class MinQueue {
		private ArrayDeque<Integer> s1Num;
		private ArrayDeque<Integer> s1Min;
		private ArrayDeque<Integer> s2Num;
		private ArrayDeque<Integer> s2Min;
		
		public MinQueue() {
			s1Num = new ArrayDeque<Integer>();
			s1Min = new ArrayDeque<Integer>();
			s2Num = new ArrayDeque<Integer>();
			s2Min = new ArrayDeque<Integer>();
		}
		
		public int queryMin() {
			int min;
			if (s1Num.isEmpty()) {
			    min = s2Min.peek();
			} else if (s2Num.isEmpty()) {
			    min = s1Min.peek();
			} else {
			    min = Math.min(s1Min.peek(),s2Min.peek()); 
			}
			return min;
		}
		
		public void add(int n) {
			int min = s1Num.isEmpty()? n : Math.min(n,s1Min.peek());
			s1Num.push(n);
			s1Min.push(min);
		}
		
		public void remove() {
			if (s2Num.isEmpty()) {
				while (!s1Num.isEmpty()) {
					int n = s1Num.pop();
					s1Min.pop();
					int min = s2Num.isEmpty() ? n : Math.min(n, s2Min.peek());
					s2Num.push(n);
					s2Min.push(min);
				}
			}
			s2Num.pop();
			s2Min.pop();
		}
	}
	
	static class DisjointSetUnion {
		  public int[] parent;
		  public int[] rank;
		  public int count;

		  public DisjointSetUnion(int nodes) {
			  count = nodes;
			  parent = new int[nodes];
			  rank = new int[nodes];
			  for (int i = 0; i < nodes; i++) {
				  parent[i] = i;
				  rank[i] = 0;
			  }
		  }
		  //"find"
		  public int root(int p) {
			  if (parent[p] != p)
				  parent[p] = root(parent[p]);
			  return parent[p];
		  }

		  //"union"
		  public void connect(int p, int q) {
			  int rootP = root(p);
			  int rootQ = root(q);
			  if (rootP == rootQ) return;
			  if (rank[rootP] < rank[rootQ]) {
				  parent[rootP] = rootQ;
			  } else if (rank[rootP] > rank[rootQ]) {
				  parent[rootQ] = rootP;
			  } else {
				  parent[rootP] = rootQ;
				  rank[rootQ] += 1;
			  }
			  count--;
		  }

		  public boolean connected(int p, int q) {
		    return root(p) == root(q);
		  }
	}
    
    public static long power(long x, long y, long p) { 
        // Initialize result
        long res = 1;
         
        // Update x if it is more   
        // than or equal to p 
        x = x % p;  
      
        while (y > 0) 
        { 
            // If y is odd, multiply x 
            // with result 
            if((y & 1)==1) 
                res = (res * x) % p; 
      
            // y must be even now 
            // y = y / 2 
            y = y >> 1;  
            x = (x * x) % p;  
        } 
        return res; 
    }
    
    public static long dist(int[] point, int[] point2) {
    	return (long)(Math.pow((point2[1]-point[1]),2)+Math.pow((point2[0]-point[0]),2));
    }
    
    public static long gcd(long a, long b) {
    	if (b == 0)
    		return a;
    	else
    		return gcd(b,a%b);
    }
    
    public static int[][] sort(int[][] array) {
    	//Sort an array (immune to quicksort TLE)
		Random rgen = new Random();
		for (int i = 0; i < array.length; i++) {
		    int randomPosition = rgen.nextInt(array.length);
		    int[] temp = array[i];
		    array[i] = array[randomPosition];
		    array[randomPosition] = temp;
		}
		Arrays.sort(array, new Comparator<int[]>() {
			  @Override
        	  public int compare(int[] arr1, int[] arr2) {
				  return arr1[2]-arr2[2]; //ascending order
	          }
		});
		return array;
	}
    
    public static long[][] sort(long[][] array) {
    	//Sort an array (immune to quicksort TLE)
		Random rgen = new Random();
		for (int i = 0; i < array.length; i++) {
		    int randomPosition = rgen.nextInt(array.length);
		    long[] temp = array[i];
		    array[i] = array[randomPosition];
		    array[randomPosition] = temp;
		}
		Arrays.sort(array, new Comparator<long[]>() {
			  @Override
        	  public int compare(long[] arr1, long[] arr2) {
				  if (arr1[0] < arr2[0])
					  return -1;
				  if (arr1[0] > arr2[0])
					  return 1;
				  return 0;
	          }
		});
		return array;
	}
    
    static class FastScanner { 
        BufferedReader br; 
        StringTokenizer st; 
  
        public FastScanner() { 
            br = new BufferedReader(new InputStreamReader(System.in)); 
        } 
  
        String next() { 
            while (st == null || !st.hasMoreElements()) { 
                try { 
                    st = new StringTokenizer(br.readLine());
                } catch (IOException  e) { 
                    e.printStackTrace(); 
                } 
            } 
            return st.nextToken(); 
        } 
  
        int ni() { 
            return Integer.parseInt(next()); 
        } 
  
        long nl() { 
            return Long.parseLong(next()); 
        } 
  
        double nd() { 
            return Double.parseDouble(next()); 
        } 
  
        String nextLine() { 
            String str = ""; 
            try { 
                str = br.readLine(); 
            } catch (IOException e) {
                e.printStackTrace(); 
            } 
            return str; 
        }
    }
}