Problem: Draw in Straight Lines

You plan to draw a black-and-white painting on a rectangular canvas. The painting will be a grid array of pixels, either black or white. You can paint black or white lines or dots on the initially white canvas.

You can apply a sequence of the following two operations in any order.

* Painting pixels on a horizontal or vertical line segment, single pixel wide and two or more pixel long, either black or white. This operation has a cost proportional to the length (the number of pixels) of the line segment multiplied by a specified coefficient in addition to a specified constant cost.
* Painting a single pixel, either black or white. This operation has a specified constant cost.



You can overpaint already painted pixels as long as the following conditions are satisfied.

* The pixel has been painted at most once before. Overpainting a pixel too many times results in too thick layers of inks, making the picture look ugly. Note that painting a pixel with the same color is also counted as overpainting. For instance, if you have painted a pixel with black twice, you can paint it neither black nor white anymore.
* The pixel once painted white should not be overpainted with the black ink. As the white ink takes very long to dry, overpainting the same pixel black would make the pixel gray, rather than black. The reverse, that is, painting white over a pixel already painted black, has no problem.



Your task is to compute the minimum total cost to draw the specified image.

Input

The input consists of a single test case. The first line contains five integers $n$, $m$, $a$, $b$, and $c$, where $n$ ($1 \leq n \leq 40$) and $m$ ($1 \leq m \leq 40$) are the height and the width of the canvas in the number of pixels, and $a$ ($0 \leq a \leq 40$), $b$ ($0 \leq b \leq 40$), and $c$ ($0 \leq c \leq 40$) are constants defining painting costs as follows. Painting a line segment of length $l$ costs $al + b$ and painting a single pixel costs $c$. These three constants satisfy $c \leq a + b$.

The next $n$ lines show the black-and-white image you want to draw. Each of the lines contains a string of length $m$. The $j$-th character of the $i$-th string is ‘#’ if the color of the pixel in the $i$-th row and the $j$-th column is to be black, and it is ‘.’ if the color is to be white.

Output

Output the minimum cost.

Sample Input 1


3 3 1 2 3
.#.

.#.


Sample Output 1


10


Sample Input 2


2 7 0 1 1
.###
.###


Sample Output 2


3


Sample Input 3


5 5 1 4 4
..#..
..#..
.##
..#..
..#..


Sample Output 3


24


Sample Input 4


7 24 1 10 10
...###..#####....###.
.#...#...#.#....#..#...#
.#..#......#....#.#.....
.#..#......#####..#.....
.#..#......#......#.....
.#...#...#.#.......#...#
...###..#........###.


Sample Output 4


256






Example

Input

3 3 1 2 3
.#.
###
.#.


Output

10

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;

using ll=long long;
#define int ll

#define rng(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,b) rng(i,0,b)
#define gnr(i,a,b) for(int i=int(b)-1;i>=int(a);i--)
#define per(i,b) gnr(i,0,b)
#define pb push_back
#define eb emplace_back
#define a first
#define b second
#define bg begin()
#define ed end()
#define all(x) x.bg,x.ed
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif

template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}

template<class t> using vc=vector<t>;
template<class t> using vvc=vc<vc<t>>;

using pi=pair<int,int>;
using vi=vc<int>;

template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
	return os<<"{"<<p.a<<","<<p.b<<"}";
}

template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
	os<<"{";
	for(auto e:v)os<<e<<",";
	return os<<"}";
}

#define mp make_pair
#define mt make_tuple
#define one(x) memset(x,-1,sizeof(x))
#define zero(x) memset(x,0,sizeof(x))
#ifdef LOCAL
void dmpr(ostream&os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ";
	dmpr(os,args...);
}
#define dmp2(...) dmpr(cerr,"Line:",__LINE__,##__VA_ARGS__)
#else
#define dmp2(...) void(0)
#endif

using uint=unsigned;
using ull=unsigned long long;

template<int i,class T>
void print_tuple(ostream&,const T&){
}

template<int i,class T,class H,class ...Args>
void print_tuple(ostream&os,const T&t){
	if(i)os<<",";
	os<<get<i>(t);
	print_tuple<i+1,T,Args...>(os,t);
}

template<class ...Args>
ostream& operator<<(ostream&os,const tuple<Args...>&t){
	os<<"{";
	print_tuple<0,tuple<Args...>,Args...>(os,t);
	return os<<"}";
}

void print(ll x,int suc=1){
	cout<<x;
	if(suc==1)
		cout<<"\n";
	if(suc==2)
		cout<<" ";
}

ll read(){
	ll i;
	cin>>i;
	return i;
}

vi readvi(int n,int off=0){
	vi v(n);
	rep(i,n)v[i]=read()+off;
	return v;
}

template<class T>
void print(const vector<T>&v,int suc=1){
	rep(i,v.size())
		print(v[i],i==int(v.size())-1?suc:2);
}

string readString(){
	string s;
	cin>>s;
	return s;
}

template<class T>
T sq(const T& t){
	return t*t;
}

//#define CAPITAL
void yes(bool ex=true){
	#ifdef CAPITAL
	cout<<"YES"<<endl;
	#else
	cout<<"Yes"<<endl;
	#endif
	if(ex)exit(0);
}
void no(bool ex=true){
	#ifdef CAPITAL
	cout<<"NO"<<endl;
	#else
	cout<<"No"<<endl;
	#endif
	if(ex)exit(0);
}

constexpr ll ten(int n){
	return n==0?1:ten(n-1)*10;
}

const ll infLL=LLONG_MAX/3;

#ifdef int
const int inf=infLL;
#else
const int inf=INT_MAX/2-100;
#endif

int topbit(signed t){
	return t==0?-1:31-__builtin_clz(t);
}
int topbit(ll t){
	return t==0?-1:63-__builtin_clzll(t);
}
int botbit(signed a){
	return a==0?32:__builtin_ctz(a);
}
int botbit(ll a){
	return a==0?64:__builtin_ctzll(a);
}
int popcount(signed t){
	return __builtin_popcount(t);
}
int popcount(ll t){
	return __builtin_popcountll(t);
}
bool ispow2(int i){
	return i&&(i&-i)==i;
}
int mask(int i){
	return (int(1)<<i)-1;
}

bool inc(int a,int b,int c){
	return a<=b&&b<=c;
}

template<class t> void mkuni(vc<t>&v){
	sort(all(v));
	v.erase(unique(all(v)),v.ed);
}

ll rand_int(ll l, ll r) { //[l, r]
	#ifdef LOCAL
	static mt19937_64 gen;
	#else
    static random_device rd;
    static mt19937_64 gen(rd());
    #endif
    return uniform_int_distribution<ll>(l, r)(gen);
}

template<class d>
struct maxflow{
	struct E{
		int to,rev;
		d cap;
	};
	vvc<E> g;
	vi itr,lv;
	maxflow(int n):g(n),itr(n),lv(n){}
	void ae(int s,int t,d c){
		g[s].pb({t,(int)g[t].size(),c});
		g[t].pb({s,(int)g[s].size()-1,0});
	}
	void bfs(int s){
		fill(all(lv),-1);
		lv[s]=0;
		queue<int> q;
		q.push(s);
		while(q.size()){
			int v=q.front();q.pop();
			for(auto e:g[v])if(e.cap>0&&lv[e.to]==-1){
				lv[e.to]=lv[v]+1;
				q.push(e.to);
			}
		}
	}
	d dfs(int v,int t,d f){
		if(v==t)return f;
		d res=0;
		for(int&i=itr[v];i<(int)g[v].size();i++){
			E& e=g[v][i];
			if(e.cap>0&&lv[e.to]==lv[v]+1){
				d a=dfs(e.to,t,min(f,e.cap));
				if(a>0){
					e.cap-=a;
					g[e.to][e.rev].cap+=a;
					res+=a;
					f-=a;
					if(f<=0)break;
				}
			}
		}
		return res;
	}
	d calc(int s,int t){
		d f=0;
		while(1){
			bfs(s);
			if(lv[t]==-1)
				return f;
			fill(all(itr),0);
			f+=dfs(s,t,inf);
		}
	}
};

const int nmax=45;
//r,c,col,vh
int id[nmax][nmax][2][2];

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);
	
	one(id);
	
	int n,m,a,b,c;cin>>n>>m>>a>>b>>c;
	vc<string> w(n);
	rep(i,n)cin>>w[i];
	
	vc<tuple<int,int,int>> es;
	int s=2;
	int ans=0;
	
	rep(i,n)rep(j,m){
		if(w[i][j]=='#'){
			int d=s++;
			int e=s++;
			id[i][j][0][0]=d;
			id[i][j][0][1]=e;
			
			es.eb(0,d,c);
			es.eb(d,1,a+b);
			es.eb(0,e,a+b);
			es.eb(e,1,c);
			es.eb(d,e,c);
			
			ans-=c;
		}else{
			int d=s++;
			int e=s++;
			id[i][j][0][0]=d;
			id[i][j][0][1]=e;
			int f=s++;
			int g=s++;
			id[i][j][1][0]=f;
			id[i][j][1][1]=g;
			
			es.eb(d,1,a+b);
			es.eb(0,e,a+b);
			es.eb(0,f,a+b);
			es.eb(g,1,a+b);
			
			es.eb(d,e,inf);
			es.eb(d,f,inf);
			es.eb(d,g,c);
			es.eb(f,e,c);
			es.eb(g,e,inf);
		}
	}
	
	maxflow<int> mf(s);
	for(auto e:es){
		int x,y,z;tie(x,y,z)=e;
		mf.ae(x,y,min(z*2,inf));
	}
	ans*=2;
	auto addleft=[&](int x,int y){
		mf.ae(x,y,b);
		mf.ae(y,x,b);
		mf.ae(x,1,b);
		mf.ae(y,1,b);
		ans-=b*2;
	};
	auto addright=[&](int x,int y){
		mf.ae(x,y,b);
		mf.ae(y,x,b);
		mf.ae(0,x,b);
		mf.ae(0,y,b);
		ans-=b*2;
	};
	
	rep(i,n-1)rep(j,m)rep(k,2){
		int x=id[i][j][k][0];
		int y=id[i+1][j][k][0];
		if(x!=-1&&y!=-1){
			if(k==0)addright(x,y);
			else addleft(x,y);
		}
	}
	rep(i,n)rep(j,m-1)rep(k,2){
		int x=id[i][j][k][1];
		int y=id[i][j+1][k][1];
		if(x!=-1&&y!=-1){
			if(k==0)addleft(x,y);
			else addright(x,y);
		}
	}
	
	ans+=mf.calc(0,1);
	
	cout<<ans/2<<endl;
}