Problem p03157 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

typedef char SINT8;
typedef short SINT16;
typedef int SINT32;
typedef long long SINT64;
typedef double DOUBLE;

#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define ABS(a) ((a) > (0) ? (a) : -(a))
#define rep(i, a, b) for (SINT64(i) = SINT64(a); (i) < SINT64(b); (i)++)
#define rrep(i, a, b) for (SINT64(i) = SINT64(a); (i) >= SINT64(b); (i)--)

#define put(a) cout << (a) << endl
#define puts(a) cout << (a) << " "

#define INF 1000000001
#define MOD 1000000007
#define INF64 1000000000000000001

#define F first
#define S second

#define Pii pair<SINT32, SINT32>
#define Pll pair<SINT64, SINT64>
#define Piii pair<SINT32, pair<SINT32, SINT32>>
#define Plll pair<SINT64, pair<SINT64, SINT64>>

#define Vll(a, b, c)    vector<vector<SINT64>> (a)((b),vector<SINT64>((c))
#define Vlll(a, b, c, d) vector<vector<vector<SINT64>>> (a)((b),vector<vector<SINT64>>((c),vector<SINT64>((d)))

using namespace std;

vector<vector<SINT64>> data(405, vector<SINT64>(405));
SINT64 H;
SINT64 W;
vector<vector<SINT64>> road(405, vector<SINT64>(405));

vector<vector<SINT64>> gg(405, vector<SINT64>(405));
SINT64 cnt = 0;

SINT64 dfs(SINT64 x, SINT64 y) {
  SINT64 buf = 0;
  SINT64 a;
  SINT64 b;
  road[x][y] = 1;

  a = x;
  b = y;
  if (a != 0) {
    a--;
    if ((data[a][b] != data[x][y]) && (road[a][b] == 0)) {
      if (data[a][b] == 0)
        buf++;
      if (data[a][b] == 1) {
        gg[a][b] = 1;
        cnt++;
      }
      buf += dfs(a, b);
    }
  }

  a = x;
  b = y;
  if (b != 0) {
    b--;
    if ((data[a][b] != data[x][y]) && (road[a][b] == 0)) {
      if (data[a][b] == 0)
        buf++;
      if (data[a][b] == 1) {
        gg[a][b] = 1;
        cnt++;
      }
      buf += dfs(a, b);
    }
  }

  a = x;
  b = y;
  if (a != H - 1) {
    a++;
    if ((data[a][b] != data[x][y]) && (road[a][b] == 0)) {
      if (data[a][b] == 0)
        buf++;
      if (data[a][b] == 1) {
        gg[a][b] = 1;
        cnt++;
      }
      buf += dfs(a, b);
    }
  }

  a = x;
  b = y;
  if (b != W - 1) {
    b++;
    if ((data[a][b] != data[x][y]) && (road[a][b] == 0)) {
      if (data[a][b] == 0)
        buf++;
      if (data[a][b] == 1) {
        gg[a][b] = 1;
        cnt++;
      }
      buf += dfs(a, b);
    }
  }

  return buf;
}

int main() {

  cin >> H;
  cin >> W;

  vector<Pll> root;

  rep(i, 0, H) {
    string s;
    cin >> s;
    rep(j, 0, W) {
      if (s[j] == '#') {
        data[i][j] = 1;
        root.emplace_back(Pll(i, j));
      }
    }
  }

  SINT64 ans = 0;
  rep(i, 0, root.size()) {
    SINT64 x, y;
    x = root[i].F;
    y = root[i].S;
    if (gg[x][y] == 0) {
      cnt = 1;
      rep(k, 0, H) { fill(road[k].begin(), road[k].end(), 0); }
      SINT64 bbb = dfs(x, y);
      ans += cnt * bbb;
    }
  }

  put(ans);
  return 0;
}

//	vector<vector<SINT64>> data(N,vector<SINT32>(3));
////2次元配列 	vector<vector<vector<SINT64>>>
//data(N,vector<vector<SINT64>>(3,vector<SINT64>(3)));		//3次元配列

//	Vll(data,N,N);		//2次元配列
//	Vlll(data,N,N,N);	//3次元配列

//	sort(data.begin(),data.end());
//	sort(data.begin(),data.end(),std::greater<SINT64>());
//	__gcd(A,B);

// 関数へのvectorポインタ渡し
// void dfs(SINT64 poi, SINT64 d, vector<vector<Pll>>& data) {
// }

/* 複数条件ソート
bool sortcompare(Pll A, Pll B) {
    if(A.F == B.F){
        return A.S > B.S;
    } else {
        return A.F < B.F;
    }
}

sort(data.begin(),data.end(),sortcompare);
*/

// タプル
// vector<tuple<SINT64,SINT64,SINT64>> edges;
// edges.emplace_back(a,b,c);
// cout << get<0>(edges[i]);
// cout << get<1>(edges[i]);
// cout << get<2>(edges[i]);
// sort(begin(edges), end(edges)); //ソート

//	data.emplace_back(BUF);			//後ろに追加

//  data.erase(std::unique(data.begin(), data.end()), data.end());
//  //ソート後に使用 同じ値を消す

//	data.insert(data.begin() + X, 0);	//X番目の要素に0を挿入

//	隣接リスト
//	vector<vector<SINT64>> data(N);
//	data[ A ].emplace_back( B );

// 両端キュー
// deque<SINT64> data;
// data.emplace_front(buf);	//先頭挿入

// lower_boundは値がなければ最大値(.size())を返す
// posi = lower_bound(data.begin(),data.end(), X) - data.begin();
// // X以上を探す posi = lower_bound(data.begin(),data.end(),make_pair(X,0)) -
// data.begin();	//pair

/* 文字列回転
        string N;
        cin >> N;
        N = N[N.length()-1] + N.substr(0,N.length()-1);

        s = to_string(i);	//ストリング変換
*/
/* 文字列合成
        string N,M;
        cin >> N >> M;
        SINT64 ans = 0;
        ans = stoi(N+M);
*/

/*  文字列変更
        string s;	cin >> s;
        rep(i,0,s.length()) {
                s[i] = (((s[i]-'A' + N) % 26) + 'A');
        }
        put(s);
*/

/*
//ワーシャルフロイド
        vector<vector<SINT64>> dist(N,vector<SINT64>(N,INF64));
        rep(i,0,N) {
                dist[i][i] = 0;
        }
        rep(k,0,N) {
                rep(i,0,N) {
                        rep(j,0,N) {
                                dist[i][j] = MIN(dist[i][j],
dist[i][k]+dist[k][j]);
                        }
                }
        }
*/

/*  優先度付きキュー
        priority_queue<SINT64, vector<SINT64>, greater<SINT64>> bufq;
   //小さいほうから取り出せる priority_queue<SINT64, vector<SINT64>> bufq;
   //大きいほうから取り出せる

        bufq.push(X);	//X を挿入
        bufq.top();		//先頭データ読み
        bufq.pop();		//先頭データ削除
*/

/* キュー
        queue<SINT64> bufq;	//宣言
        bufq.push(0);	//挿入
        bufq.front();	//先頭データ読み
        bufq.pop();		//先頭データ削除
*/

/* SET コンテナ
        set<SINT64> data;
        data.insert(X);				//X を挿入
        data.erase(data.begin());	//先頭を削除
        data.erase(--data.end());	//末尾を削除
        *data.begin();				//先頭要素にアクセス
        *data.rbegin();				//末尾要素にアクセス

        //全表示
    set<SINT64>::iterator it; //イテレータを用意
    for(it = data.begin(); it != data.end(); it++) {
        cout << *it << " ";
    }
        cout << endl;

        //N番目を一部表示
        set<SINT64>::iterator it; //  イテレータを用意
        it = data.begin();
        rep (i,0,N) {
                it++;
        }
        cout << *it << endl;
*/

/* map
        map<string,SINT32> mp;
        SINT32 N = 0;
        SINT32 mx = 0;

        cin >> N;
        for (SINT32 i = 0; i < N; i++) {
                string s;
                cin >> s;
                mp[s]++;
        }
        for(auto it=mp.begin();it!=mp.end();it++) {
                mx=max(mx,it->second);
        }

        //abc146E
        map<SINT64,SINT64> mp;
        rep(i,0,N+1) {
                ans += mp[rui[i]];
                mp[rui[i]]++;
                bufq.push(rui[i]);
                if (bufq.size() == M) {
                        mp[bufq.front()]--;
                        bufq.pop();
                }
        }
*/

/*
        //順列全表示
        //sortしてからでないと全列挙にならない
        sort(data.begin(),data.end());
        do {
                cout << buf << endl;
                rep(i,0,R) {
                        cout << data[i] << " ";
                }
                cout << endl;

    } while (next_permutation(data.begin(),data.end()));
*/

/* bit数数え上げ
SINT64 bits64(SINT64 bits)
{
    bits = (bits & 0x55555555) + (bits >> 1 & 0x55555555);
    bits = (bits & 0x33333333) + (bits >> 2 & 0x33333333);
    bits = (bits & 0x0f0f0f0f) + (bits >> 4 & 0x0f0f0f0f);
    bits = (bits & 0x00ff00ff) + (bits >> 8 & 0x00ff00ff);
    return (bits & 0x0000ffff) + (bits >>16 & 0x0000ffff);
}
*/

// bitシフトのLONG対応
//  ans += (1L<<50);

//  桁指定表示
//  ans = ans * M_PI;
//	cout << setprecision(15) << ans << endl;

// 桁数0埋め
// cout << std::setfill('0') << std::right << std::setw(2) << 5; //05

// 逆元　コンビネーション
/*
SINT64 modpow(SINT64 a, SINT64 p) {
        if (p == 0) return 1;
        if (p % 2 == 0) {
                //pが偶数の時
                SINT64 halfP = p / 2;
                SINT64 half = modpow(a, halfP);
                //a^(p/2) をhalfとして、half*halfを計算
                return half * half % MOD;
        } else {
                //pが奇数の時は、偶数にするために1減らす
                return a * modpow(a, p - 1) % MOD;
        }
}

SINT64 calcComb(SINT64 a, SINT64 b) {
        SINT64 Mul = 1;
        SINT64 Div = 1;
        SINT64 ans = 0;

        if (b > a - b) {
                return calcComb(a, a - b);
        }

        rep(i,0,b) {
                Mul *= (a - i);
                Div *= (i + 1);
                Mul %= MOD;
                Div %= MOD;
        }
        ans = Mul * modpow(Div, MOD - 2) % MOD;
        return ans;
}
*/

/* UNION FIND
class UnionFind {
public:
        vector<SINT64> parent;

        UnionFind(SINT64 N) {
                parent = vector<SINT64>(N+10, -1);	//少し多めに
        }

        SINT64 root(SINT64 A) {
                if (parent[A] < 0) {
                        return A;
                } else {
                        parent[A] = root(parent[A]);
                        return parent[A];
                }
        }

        SINT64 size(SINT64 A) {
                return parent[root(A)] * (-1);
        }

        bool judge(SINT64 A, SINT64 B) {
                A = root(A);
                B = root(B);
                if (A == B) {
                        return true;	//同じグループ
                } else {
                        return false;	//違うグループ
                }
        }

        void connect(SINT64 A, SINT64 B) {
                A = root(A);
                B = root(B);
                if (A != B) {
                        if (size(A) < size(B)) {
                                swap(A, B);
                        }
                        parent[A] += parent[B];
                        parent[B] = A;
                }
        }
};
UnionFind uni(N);
 */

/*
class SegTree {
private:
        SINT64 size;
        vector<SINT64> node;

        SINT64 jugdement(SINT64 a, SINT64 b) {
                SINT64 ans = 0;
                ans = a+b;
                return ans;
        }

public:

        //コンストラクタ
        SegTree(vector<SINT64> data) {
                SINT64 ori_size;
                ori_size = data.size();
                size = 1;
                while (size < ori_size) {
                        size *= 2;
                }
                node.resize(2*size-1, 0);

                rep(i,0,ori_size) {
                        node[size-1+i] = data[i];
                }
                rrep(i,size-2,0) {
                        node[i] = jugdement(node[2*i+1], node[2*i+2]);
                }
        }

        //データ更新
        void update(SINT64 x, SINT64 val) {
                x += (size - 1);
        node[x] = val+node[x];
        while(x > 0) {
                x = (x - 1) / 2;
                node[x] = jugdement(node[2*x+1], node[2*x+2]);
                }
        }

        //データ取得 [a,b)
        SINT64 getdata(SINT64 a, SINT64 b, SINT64 k = 0, SINT64 l = 0, SINT64 r
= -1) { if (r < 0) { r = size;
                }

                //要求範囲外
                if ((r <= a) || (b <= l)) {
                        return 0;
                }
                //完全要求区間内
                if ((a <= l) && (r <= b)) {
                        return node[k];
                }

        SINT64 vl = getdata(a, b, 2*k+1, l, (l+r)/2);
        SINT64 vr = getdata(a, b, 2*k+2, (l+r)/2, r);
        return jugdement(vl, vr);
        }

        //表示
        void disp() {
                rep(i,0,size) {
                        puts(node[size-1+i]);
                } cout << endl;
        }

        void alldisp() {
                SINT64 cnt = 0;
                SINT64 end = 2;

                while (1) {
                        puts(node[cnt]);
                        if (cnt == end-2) {
                                end *= 2;
                                cout << endl;
                        }
                        cnt++;
                        if (cnt == size*2-1) {
                                break;
                        }
                }
        }
};

SegTree seg(N);
 */

Fixed submission:
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

typedef char SINT8;
typedef short SINT16;
typedef int SINT32;
typedef long long SINT64;
typedef double DOUBLE;

#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define ABS(a) ((a) > (0) ? (a) : -(a))
#define rep(i, a, b) for (SINT64(i) = SINT64(a); (i) < SINT64(b); (i)++)
#define rrep(i, a, b) for (SINT64(i) = SINT64(a); (i) >= SINT64(b); (i)--)

#define put(a) cout << (a) << endl
#define puts(a) cout << (a) << " "

#define INF 1000000001
#define MOD 1000000007
#define INF64 1000000000000000001

#define F first
#define S second

#define Pii pair<SINT32, SINT32>
#define Pll pair<SINT64, SINT64>
#define Piii pair<SINT32, pair<SINT32, SINT32>>
#define Plll pair<SINT64, pair<SINT64, SINT64>>

#define Vll(a, b, c)    vector<vector<SINT64>> (a)((b),vector<SINT64>((c))
#define Vlll(a, b, c, d) vector<vector<vector<SINT64>>> (a)((b),vector<vector<SINT64>>((c),vector<SINT64>((d)))

using namespace std;

vector<vector<SINT64>> data(405, vector<SINT64>(405));
SINT64 H;
SINT64 W;
vector<vector<SINT64>> road(405, vector<SINT64>(405));

vector<vector<SINT64>> gg(405, vector<SINT64>(405));
SINT64 cnt = 0;

SINT64 dfs(SINT64 x, SINT64 y) {
  SINT64 buf = 0;
  SINT64 a;
  SINT64 b;
  road[x][y] = 1;

  a = x;
  b = y;
  if (a != 0) {
    a--;
    if ((data[a][b] != data[x][y]) && (road[a][b] == 0)) {
      if (data[a][b] == 0)
        buf++;
      if (data[a][b] == 1) {
        gg[a][b] = 1;
        cnt++;
      }
      buf += dfs(a, b);
    }
  }

  a = x;
  b = y;
  if (b != 0) {
    b--;
    if ((data[a][b] != data[x][y]) && (road[a][b] == 0)) {
      if (data[a][b] == 0)
        buf++;
      if (data[a][b] == 1) {
        gg[a][b] = 1;
        cnt++;
      }
      buf += dfs(a, b);
    }
  }

  a = x;
  b = y;
  if (a != H - 1) {
    a++;
    if ((data[a][b] != data[x][y]) && (road[a][b] == 0)) {
      if (data[a][b] == 0)
        buf++;
      if (data[a][b] == 1) {
        gg[a][b] = 1;
        cnt++;
      }
      buf += dfs(a, b);
    }
  }

  a = x;
  b = y;
  if (b != W - 1) {
    b++;
    if ((data[a][b] != data[x][y]) && (road[a][b] == 0)) {
      if (data[a][b] == 0)
        buf++;
      if (data[a][b] == 1) {
        gg[a][b] = 1;
        cnt++;
      }
      buf += dfs(a, b);
    }
  }

  return buf;
}

int main() {

  cin >> H;
  cin >> W;

  vector<Pll> root;

  rep(i, 0, H) {
    string s;
    cin >> s;
    rep(j, 0, W) {
      if (s[j] == '#') {
        data[i][j] = 1;
        root.emplace_back(Pll(i, j));
      }
    }
  }

  SINT64 ans = 0;
  rep(i, 0, root.size()) {
    SINT64 x, y;
    x = root[i].F;
    y = root[i].S;
    if (gg[x][y] == 0) {
      cnt = 1;

      SINT64 bbb = dfs(x, y);
      ans += cnt * bbb;
    }
  }

  put(ans);
  return 0;
}

//	vector<vector<SINT64>> data(N,vector<SINT32>(3));
////2次元配列 	vector<vector<vector<SINT64>>>
//data(N,vector<vector<SINT64>>(3,vector<SINT64>(3)));		//3次元配列

//	Vll(data,N,N);		//2次元配列
//	Vlll(data,N,N,N);	//3次元配列

//	sort(data.begin(),data.end());
//	sort(data.begin(),data.end(),std::greater<SINT64>());
//	__gcd(A,B);

// 関数へのvectorポインタ渡し
// void dfs(SINT64 poi, SINT64 d, vector<vector<Pll>>& data) {
// }

/* 複数条件ソート
bool sortcompare(Pll A, Pll B) {
    if(A.F == B.F){
        return A.S > B.S;
    } else {
        return A.F < B.F;
    }
}

sort(data.begin(),data.end(),sortcompare);
*/

// タプル
// vector<tuple<SINT64,SINT64,SINT64>> edges;
// edges.emplace_back(a,b,c);
// cout << get<0>(edges[i]);
// cout << get<1>(edges[i]);
// cout << get<2>(edges[i]);
// sort(begin(edges), end(edges)); //ソート

//	data.emplace_back(BUF);			//後ろに追加

//  data.erase(std::unique(data.begin(), data.end()), data.end());
//  //ソート後に使用 同じ値を消す

//	data.insert(data.begin() + X, 0);	//X番目の要素に0を挿入

//	隣接リスト
//	vector<vector<SINT64>> data(N);
//	data[ A ].emplace_back( B );

// 両端キュー
// deque<SINT64> data;
// data.emplace_front(buf);	//先頭挿入

// lower_boundは値がなければ最大値(.size())を返す
// posi = lower_bound(data.begin(),data.end(), X) - data.begin();
// // X以上を探す posi = lower_bound(data.begin(),data.end(),make_pair(X,0)) -
// data.begin();	//pair

/* 文字列回転
        string N;
        cin >> N;
        N = N[N.length()-1] + N.substr(0,N.length()-1);

        s = to_string(i);	//ストリング変換
*/
/* 文字列合成
        string N,M;
        cin >> N >> M;
        SINT64 ans = 0;
        ans = stoi(N+M);
*/

/*  文字列変更
        string s;	cin >> s;
        rep(i,0,s.length()) {
                s[i] = (((s[i]-'A' + N) % 26) + 'A');
        }
        put(s);
*/

/*
//ワーシャルフロイド
        vector<vector<SINT64>> dist(N,vector<SINT64>(N,INF64));
        rep(i,0,N) {
                dist[i][i] = 0;
        }
        rep(k,0,N) {
                rep(i,0,N) {
                        rep(j,0,N) {
                                dist[i][j] = MIN(dist[i][j],
dist[i][k]+dist[k][j]);
                        }
                }
        }
*/

/*  優先度付きキュー
        priority_queue<SINT64, vector<SINT64>, greater<SINT64>> bufq;
   //小さいほうから取り出せる priority_queue<SINT64, vector<SINT64>> bufq;
   //大きいほうから取り出せる

        bufq.push(X);	//X を挿入
        bufq.top();		//先頭データ読み
        bufq.pop();		//先頭データ削除
*/

/* キュー
        queue<SINT64> bufq;	//宣言
        bufq.push(0);	//挿入
        bufq.front();	//先頭データ読み
        bufq.pop();		//先頭データ削除
*/

/* SET コンテナ
        set<SINT64> data;
        data.insert(X);				//X を挿入
        data.erase(data.begin());	//先頭を削除
        data.erase(--data.end());	//末尾を削除
        *data.begin();				//先頭要素にアクセス
        *data.rbegin();				//末尾要素にアクセス

        //全表示
    set<SINT64>::iterator it; //イテレータを用意
    for(it = data.begin(); it != data.end(); it++) {
        cout << *it << " ";
    }
        cout << endl;

        //N番目を一部表示
        set<SINT64>::iterator it; //  イテレータを用意
        it = data.begin();
        rep (i,0,N) {
                it++;
        }
        cout << *it << endl;
*/

/* map
        map<string,SINT32> mp;
        SINT32 N = 0;
        SINT32 mx = 0;

        cin >> N;
        for (SINT32 i = 0; i < N; i++) {
                string s;
                cin >> s;
                mp[s]++;
        }
        for(auto it=mp.begin();it!=mp.end();it++) {
                mx=max(mx,it->second);
        }

        //abc146E
        map<SINT64,SINT64> mp;
        rep(i,0,N+1) {
                ans += mp[rui[i]];
                mp[rui[i]]++;
                bufq.push(rui[i]);
                if (bufq.size() == M) {
                        mp[bufq.front()]--;
                        bufq.pop();
                }
        }
*/

/*
        //順列全表示
        //sortしてからでないと全列挙にならない
        sort(data.begin(),data.end());
        do {
                cout << buf << endl;
                rep(i,0,R) {
                        cout << data[i] << " ";
                }
                cout << endl;

    } while (next_permutation(data.begin(),data.end()));
*/

/* bit数数え上げ
SINT64 bits64(SINT64 bits)
{
    bits = (bits & 0x55555555) + (bits >> 1 & 0x55555555);
    bits = (bits & 0x33333333) + (bits >> 2 & 0x33333333);
    bits = (bits & 0x0f0f0f0f) + (bits >> 4 & 0x0f0f0f0f);
    bits = (bits & 0x00ff00ff) + (bits >> 8 & 0x00ff00ff);
    return (bits & 0x0000ffff) + (bits >>16 & 0x0000ffff);
}
*/

// bitシフトのLONG対応
//  ans += (1L<<50);

//  桁指定表示
//  ans = ans * M_PI;
//	cout << setprecision(15) << ans << endl;

// 桁数0埋め
// cout << std::setfill('0') << std::right << std::setw(2) << 5; //05

// 逆元　コンビネーション
/*
SINT64 modpow(SINT64 a, SINT64 p) {
        if (p == 0) return 1;
        if (p % 2 == 0) {
                //pが偶数の時
                SINT64 halfP = p / 2;
                SINT64 half = modpow(a, halfP);
                //a^(p/2) をhalfとして、half*halfを計算
                return half * half % MOD;
        } else {
                //pが奇数の時は、偶数にするために1減らす
                return a * modpow(a, p - 1) % MOD;
        }
}

SINT64 calcComb(SINT64 a, SINT64 b) {
        SINT64 Mul = 1;
        SINT64 Div = 1;
        SINT64 ans = 0;

        if (b > a - b) {
                return calcComb(a, a - b);
        }

        rep(i,0,b) {
                Mul *= (a - i);
                Div *= (i + 1);
                Mul %= MOD;
                Div %= MOD;
        }
        ans = Mul * modpow(Div, MOD - 2) % MOD;
        return ans;
}
*/

/* UNION FIND
class UnionFind {
public:
        vector<SINT64> parent;

        UnionFind(SINT64 N) {
                parent = vector<SINT64>(N+10, -1);	//少し多めに
        }

        SINT64 root(SINT64 A) {
                if (parent[A] < 0) {
                        return A;
                } else {
                        parent[A] = root(parent[A]);
                        return parent[A];
                }
        }

        SINT64 size(SINT64 A) {
                return parent[root(A)] * (-1);
        }

        bool judge(SINT64 A, SINT64 B) {
                A = root(A);
                B = root(B);
                if (A == B) {
                        return true;	//同じグループ
                } else {
                        return false;	//違うグループ
                }
        }

        void connect(SINT64 A, SINT64 B) {
                A = root(A);
                B = root(B);
                if (A != B) {
                        if (size(A) < size(B)) {
                                swap(A, B);
                        }
                        parent[A] += parent[B];
                        parent[B] = A;
                }
        }
};
UnionFind uni(N);
 */

/*
class SegTree {
private:
        SINT64 size;
        vector<SINT64> node;

        SINT64 jugdement(SINT64 a, SINT64 b) {
                SINT64 ans = 0;
                ans = a+b;
                return ans;
        }

public:

        //コンストラクタ
        SegTree(vector<SINT64> data) {
                SINT64 ori_size;
                ori_size = data.size();
                size = 1;
                while (size < ori_size) {
                        size *= 2;
                }
                node.resize(2*size-1, 0);

                rep(i,0,ori_size) {
                        node[size-1+i] = data[i];
                }
                rrep(i,size-2,0) {
                        node[i] = jugdement(node[2*i+1], node[2*i+2]);
                }
        }

        //データ更新
        void update(SINT64 x, SINT64 val) {
                x += (size - 1);
        node[x] = val+node[x];
        while(x > 0) {
                x = (x - 1) / 2;
                node[x] = jugdement(node[2*x+1], node[2*x+2]);
                }
        }

        //データ取得 [a,b)
        SINT64 getdata(SINT64 a, SINT64 b, SINT64 k = 0, SINT64 l = 0, SINT64 r
= -1) { if (r < 0) { r = size;
                }

                //要求範囲外
                if ((r <= a) || (b <= l)) {
                        return 0;
                }
                //完全要求区間内
                if ((a <= l) && (r <= b)) {
                        return node[k];
                }

        SINT64 vl = getdata(a, b, 2*k+1, l, (l+r)/2);
        SINT64 vr = getdata(a, b, 2*k+2, (l+r)/2, r);
        return jugdement(vl, vr);
        }

        //表示
        void disp() {
                rep(i,0,size) {
                        puts(node[size-1+i]);
                } cout << endl;
        }

        void alldisp() {
                SINT64 cnt = 0;
                SINT64 end = 2;

                while (1) {
                        puts(node[cnt]);
                        if (cnt == end-2) {
                                end *= 2;
                                cout << endl;
                        }
                        cnt++;
                        if (cnt == size*2-1) {
                                break;
                        }
                }
        }
};

SegTree seg(N);
 */