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.util.*;
 
 
 
public class Main {
	
	static InputReader in = new InputReader(System.in);
	static PrintWriter out = new PrintWriter(System.out);
	
	static int oo = (int)1e9;
//	static long oo = (long)1e15;
//	static int mod = 1_000_000_007;
	static int mod = 998244353;
	
	static int[] di = {1, 0, 0, -1};
	static int[] dj = {0, -1, 1, 0};
	
	static int M = 40;
	static double EPS = 1e-13;
	
	
	public static void main(String[] args) throws IOException {

		int n = in.nextInt();
		int m = in.nextInt();
		int a = in.nextInt();
		int b = in.nextInt();
		
		long g = in.nextLong();
		long x = in.nextLong();
		long y = in.nextLong();
		long z = in.nextLong();
		int[][] grid = new int[n][m];
		for(int i = 0; i < n; ++i) {
			for(int j = 0; j < m; ++j) {
				grid[i][j] = (int)g;
				g = (g * x + y) % z;
			}
		}
		int[][] ans = new int[n][m];
		for(int j = 0; j < m; ++j) {
			ArrayDeque<Integer> dq = new ArrayDeque<Integer>();
			int i = 0;
			for(; i < a; ++i) {
				while(!dq.isEmpty() && dq.peekLast() > grid[i][j])
					dq.pollLast();
				dq.add(grid[i][j]);
			}
			ans[i-a][j] = dq.peekFirst();
			for(; i < n; ++i) {
				while(!dq.isEmpty() && dq.peekLast() > grid[i][j])
					dq.pollLast();
				dq.add(grid[i][j]);
				if(grid[i-a][j] == dq.peekFirst())
					dq.pollFirst();
				ans[i-a+1][j] = dq.peekFirst();
			}
			
//			int[][] st = new int[n][12];
//			for(int k = 0; k < 12; ++k) {
//				for(int i = 0; i < n; ++i) {
//					int ni = i + (1<<(k-1));
//					st[i][k] = k == 0 ? grid[i][j] : Math.min( st[i][k-1], (ni >= n ? oo : st[ni][k-1]) );
//				}
//			}
//			i: for(int i = 0; i < n; ++i) {
//				int ii = i, aa = a;
//				int min = oo;
//				for(int k = 12; k >= 0; --k) {
//					if(aa >= (1<<k)) {
//						if(ii >= n)
//							break i;
//						min = Math.min(st[ii][k], min);
//						ii += (1<<k);
//						aa -= (1<<k);
//					}
//				}
//				ans[i][j] = min;
//			}
			
//			TreeMap<Integer, Integer> map = new TreeMap<>();
//			int i = 0;
//			for(; i < a; ++i) {
//				map.put(grid[i][j], map.getOrDefault(grid[i][j], 0) + 1);
//			}
//			ans[i-a][j] = map.firstKey();
//			for(; i < n; ++i) {
//				map.put(grid[i][j], map.getOrDefault(grid[i][j], 0) + 1);
//				int cnt = map.getOrDefault(grid[i-a][j], 0) - 1;
//				if(cnt == 0)
//					map.remove(grid[i-a][j]);
//				else
//					map.put(grid[i-a][j], cnt);
//				ans[i-a+1][j] = map.firstKey();
//			}
		}
		int[][] ans2 = new int[n][m];
		for(int i = 0; i < n; ++i) {
			ArrayDeque<Integer> dq = new ArrayDeque<Integer>();
			int j = 0;
			for(; j < b; ++j) {
				while(!dq.isEmpty() && dq.peekLast() > ans[i][j])
					dq.pollLast();
				dq.add(ans[i][j]);
			}
			ans2[i][j-b] = dq.peekFirst();
			for(; j < m; ++j) {
				while(!dq.isEmpty() && dq.peekLast() > ans[i][j])
					dq.pollLast();
				dq.add(ans[i][j]);
				if(ans[i][j-b] == dq.peekFirst())
					dq.pollFirst();
				ans2[i][j-b+1] = dq.peekFirst();
			}
			
//			int[][] st = new int[m][12];
//			for(int k = 0; k < 12; ++k) {
//				for(int j = 0; j < m; ++j) {
//					int nj = j + (1<<(k-1));
//					st[j][k] = k == 0 ? ans[i][j] : Math.min( st[j][k-1], (nj >= m ? oo : st[nj][k-1]) );
//				}
//			}
//			j: for(int j = 0; j < m; ++j) {
//				int jj = j, bb = b;
//				int min = oo;
//				for(int k = 12; k >= 0; --k) {
//					if(bb >= (1<<k)) {
//						if(jj >= m)
//							break j;
//						min = Math.min(st[jj][k], min);
//						jj += (1<<k);
//						bb -= (1<<k);
//					}
//				}
//				ans2[i][j] = min;
//			}
			
//			TreeMap<Integer, Integer> map = new TreeMap<>();
//			int j = 0;
//			for(; j < b; ++j) {
//				map.put(ans[i][j], map.getOrDefault(ans[i][j], 0) + 1);
//			}
//			ans2[i][j-b] = map.firstKey();
//			for(; j < m; ++j) {
//				map.put(ans[i][j], map.getOrDefault(ans[i][j], 0) + 1);
//				int cnt = map.getOrDefault(ans[i][j-b], 0) - 1;
//				if(cnt == 0)
//					map.remove(ans[i][j-b]);
//				else
//					map.put(ans[i][j-b], cnt);
//				ans2[i][j-b+1] = map.firstKey();
//			}
		}
		long sum = 0;
		for(int i = 0; i <= n-a; ++i) {
			for(int j = 0; j <= m-b; ++j) {
				sum += ans2[i][j];
			}
		}
		System.out.println(sum);
		
		out.close();
	}
	
	
	static int find(int[] g, int x) {
		return g[x] = g[x] == x ? x : find(g, g[x]);
	}
	
	static void union(int[] g, int[] size, int x, int y) {
		x = find(g, x); y = find(g, y);
		if(x == y)
			return;
		if(size[x] < size[y]) {
			g[x] = y;
			size[y] += size[x];
		}
		else {
			g[y] = x;
			size[x] += size[y];
		}
	}
	
	static class Segment {
		Segment left, right;
		int size, val;
		int time, lazy;
		
		public Segment(int[] a, int l, int r) {
			super();
			if(l == r) {
				return;
			}
			int mid = (l + r) / 2;
			left = new Segment(a, l, mid);
			right = new Segment(a, mid+1, r);
		}
		
		boolean covered(int ll, int rr, int l, int r) {
			return ll <= l && rr >= r;
		}
		
		boolean noIntersection(int ll, int rr, int l, int r) {
			return ll > r || rr < l;
		}
		
		void lazyPropagation() {
			if(lazy != 0) {
				if(left != null) {
					left.setLazy(this.time, this.lazy);
					right.setLazy(this.time, this.lazy);
				}
				else {
					val = lazy;
				}
			}
		}
		
		void setLazy(int time, int lazy) {
			if(this.time != 0 && this.time <= time)
				return;
			this.time = time;
			this.lazy = lazy;
		}
		
		int query(int ll, int rr, int l, int r) {
			lazyPropagation();
			if(noIntersection(ll, rr, l, r))
				return 0;
			if(covered(ll, rr, l, r))
				return val;
			int mid = (l + r) / 2;
			int leftSum = left.query(ll, rr, l, mid);
			int rightSum = right.query(ll, rr, mid+1, r);
			return leftSum + rightSum;
		}
		
		int query(int k, int l, int r) {
			Segment trace = this;
			while(l < r) {
				int mid = (l + r) / 2;
				if(trace.left.size > k) {
					trace = trace.left;
					r = mid;
				}
				else {
					k -= trace.left.size;
					trace = trace.right;
					l = mid + 1;
				}
			}
			return l;
		}
		
		void update(int ll, int rr, int time, int knight, int l, int r) {
			lazyPropagation();
			if(noIntersection(ll, rr, l, r))
				return;
			if(covered(ll, rr, l, r)) {
				setLazy(time, knight);
				return;
			}
			int mid = (l + r) / 2;
			left.update(ll, rr, time, knight, l, mid);
			right.update(ll, rr, time, knight, mid+1, r);
		}
	}
	
	static long pow(long a, long n, long mod) {
		if(n == 0)
			return 1;
		if(n % 2 == 1)
			return a * pow(a, n-1, mod) % mod;
		long x = pow(a, n / 2, mod);
		return x * x % mod;
	}
	
	
	static int[] getPi(char[] a) {
		int m = a.length;
		int j = 0;
		int[] pi = new int[m];
		for(int i = 1; i < m; ++i) {
			while(j > 0 && a[i] != a[j])
				j = pi[j-1];
			if(a[i] == a[j]) {
				pi[i] = j + 1;
				j++;
			}
		}
		return pi;
	}
	
	static long lcm(long a, long b) {
		return a * b / gcd(a, b);
	}
	
	static boolean nextPermutation(int[] a) {
		for(int i = a.length - 2; i >= 0; --i) {
			if(a[i] < a[i+1]) {
				for(int j = a.length - 1; ; --j) {
					if(a[i] < a[j]) {
						int t = a[i];
						a[i] = a[j];
						a[j] = t;
						for(i++, j = a.length - 1; i < j; ++i, --j) {
							t = a[i];
							a[i] = a[j];
							a[j] = t;
						}
						return true;
					}
				}
			}
		}
		return false;
	}
	
	static void shuffle(Object[] a) {
		Random r = new Random();
		for(int i = a.length - 1; i > 0; --i) {
			int si = r.nextInt(i);
			Object t = a[si];
			a[si] = a[i];
			a[i] = t;
		}
	}
	
	static void shuffle(int[] a) {
		Random r = new Random();
		for(int i = a.length - 1; i > 0; --i) {
			int si = r.nextInt(i);
			int t = a[si];
			a[si] = a[i];
			a[i] = t;
		}
	}
	
	static void shuffle(long[] a) {
		Random r = new Random();
		for(int i = a.length - 1; i > 0; --i) {
			int si = r.nextInt(i);
			long t = a[si];
			a[si] = a[i];
			a[i] = t;
		}
	}
	
	static int lower_bound(int[] a, int n, int k) {
		int s = 0;
		int e = n;
		int m;
		while (e - s > 0) {
			m = (s + e) / 2;
			if (a[m] < k)
				s = m + 1;
			else
				e = m;
		}
		return e;
	}
	static int lower_bound(long[] a, int n, long k) {
		int s = 0;
		int e = n;
		int m;
		while (e - s > 0) {
			m = (s + e) / 2;
			if (a[m] < k)
				s = m + 1;
			else
				e = m;
		}
		return e;
	}
	
	static int gcd(int a, int b) {
		return b == 0 ? a : gcd(b, a % b);
	}
	static long gcd(long a, long b) {
		return b == 0 ? a : gcd(b, a % b);
	}
	
	static class Pair implements Comparable<Pair> {
		int first, second;
 
		public Pair(int first, int second) {
			super();
			this.first = first;
			this.second = second;
		}
 
		@Override
		public int compareTo(Pair o) {
			return this.first != o.first ? this.first - o.first : this.second - o.second;
		}
		
//		@Override
//		public int compareTo(Pair o) {
//			return this.first != o.first ? o.first - this.first : o.second - this.second;
//		}
 
		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + first;
			result = prime * result + second;
			return result;
		}
 
		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			Pair other = (Pair) obj;
			if (first != other.first)
				return false;
			if (second != other.second)
				return false;
			return true;
		}
	}
}
 
 
 
class InputReader {
 
	private final InputStream stream;
	private final byte[] buf = new byte[8192];
	private int curChar, snumChars;
 
	public InputReader(InputStream st) {
		this.stream = st;
	}
 
	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 res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}
 
	public long nextLong() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}
 
	public int[] nextIntArray(int n) {
		int a[] = new int[n];
		for (int i = 0; i < n; i++) {
			a[i] = nextInt();
		}
		return a;
	}
 
	public String readString() {
		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;
	}
 
	private boolean isEndOfLine(int c) {
		return c == '\n' || c == '\r' || c == -1;
	}
 
}