/*
*/
// #pragma GCC optimize("Ofast")
// #pragma GCC target("avx,avx2,fma")
#include <iostream>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <stack>
#include <deque>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <utility>
#include <bitset>
#include <random>
#include <chrono>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
#define EPS 1e-9
#define CeilDiv(a, b) ((a + b - 1) / b)
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int, int> pi;
typedef pair<int, double> pid;
typedef pair<ll, ll> pll;
typedef pair<double, double> pd;
typedef tree<pi, null_type, less<pi>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
// Comment out #include<iostream>
//ifstream cin("cbs.in");
//ofstream cout("cbs.out");
vector<vector<int>> Get_Psum(const vector<string>& brackets)
{
int k = brackets.size(), n = brackets[0].size();
vector<vector<int>> psum(k, vector<int>(n));
for(int i = 0; i < k; ++i)
{
for(int j = 0; j < n; ++j)
{
int val = (brackets[i][j] == '(') ? 1 : -1;
psum[i][j] = val;
if(j > 0) psum[i][j] += psum[i][j-1];
}
}
return psum;
}
vector<vector<int>> Get_NearestLeft(const vector<vector<int>>& psum)
{
int k = psum.size(), n = psum[0].size();
vector<vector<int>> res(k, vector<int>(n, -1));
for(int i = 0; i < k; ++i)
{
stack<int> st;
for(int j = n-1; j >= 0; --j)
{
while(!st.empty() && psum[i][j] < psum[i][st.top()])
{
res[i][st.top()] = j;
st.pop();
}
st.push(j);
}
}
return res;
}
void Solve(const int &tc = 1)
{
int k, n;
cin >> k >> n;
vector<string> brackets(k);
for(auto& v : brackets)
{
cin >> v;
}
vector<vector<int>> psum = Get_Psum(brackets);
vector<vector<int>> nearest_left = Get_NearestLeft(psum);
vector<int> super_psum(n);
for(int i = 0; i < k; ++i)
{
for(int j = 0; j < n; ++j)
{
super_psum[j] += psum[i][j];
}
}
ll ans = 0;
map<int, vector<int>> idx_of;
// How many concurrently balanced substring ends at index j
for(int j = 0; j < n; ++j)
{
// All brackets[i][j] needs to be )
bool all_close = true;
for(int i = 0; i < k; ++i)
{
all_close &= (brackets[i][j] == ')');
}
if(all_close)
{
// Get max left boundary
int mx_left = -1;
for (int i = 0; i < k; ++i)
{
mx_left = max(mx_left, nearest_left[i][j]);
}
// How many target_sum with max_left < idx < j
int target_sum = super_psum[j];
ans += ((int)idx_of[target_sum].size() -
(upper_bound(idx_of[target_sum].begin(), idx_of[target_sum].end(), mx_left) - idx_of[target_sum].begin()));
}
idx_of[super_psum[j]].push_back(j);
}
cout << ans << "\n";
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
//cout << fixed << setprecision(9);
int tc = 1;
//cin >> tc;
for (int i = 1; i <= tc; ++i)
{
Solve(i);
}
return 0;
}