Problem:
Escape
頂点に正の値を持つ無向グラフが与えられる。
頂点には 1 から
N
の番号がついており、
i
番目の頂点は
w_i
の値を持っている。
1 番目の頂点からスタートし、直前に通った辺を通ることができないという制約のもとでグラフ上を移動することができる。
各頂点では，初めて訪れた時に限りその頂点が持つ値の点数を得られる。
取得できる点数の総和の最大値を求めよ。
Constraints
1  ≤  N  ≤  100000
N − 1  ≤  M  ≤  100000
1  ≤  w_i  ≤  1000
1  ≤  u_i, v_i  ≤  N
多重辺・自己辺は存在しない
グラフは連結である
Input Format
入力は以下の形式で標準入力から与えられる。
N
M
w_1
w_2
...
w_N
u_1
v_1
u_2
v_2
...
u_M
v_M
1
行目には
グラフ
の頂点数
N
と辺の数を表す整数
M
が入力される。
2
行目には各頂点が持つ値
w_i
が入力される。
さらに続けて
M
行に、各辺により繋がれる
2
頂点の番号が入力される。
Output Format
答えを1行に出力せよ。
Sample Input 1
6 6
1 2 3 4 5 6
1 2
2 3
3 4
1 4
4 5
5 6
Sample Output 1
21
頂点 1→2→3→4→5→6 と進むことで全ての頂点の点数を集めることができます。
Sample Input 2
7 8
1 3 3 5 2 2 3
1 2
2 3
3 1
1 4
1 7
1 5
1 6
5 6
Sample Output 2
16
頂点 1→2→3→1→5→6→1→4 と進むことで16点を集めることができます。

Submitted solutions:

code_snippet: #include<iostream>
#include<vector>
#include<utility>

using namespace std;

typedef pair<int, int> Pii;

vector<int> graph[100001];
vector<int> dim(100001, 0);
vector<Pii> nodes(100001);
vector<bool> used(100001, false);

int dfs(int node, int prev){
    used[node] = true;
    int max_cost = 0, not_zero = 0, cost;
    nodes[node].second = 0;
    for(int nxt: graph[node]){
        if(nxt == prev || used[nxt]) continue;
        cost = dfs(nxt, node);
        if(cost){
            not_zero++;
            dim[node]--;
        }
        max_cost = max(max_cost, cost);
    }
    nodes[node].second = max_cost;

    if(dim[node] == 1 && node != 0){
        int total = nodes[node].first + nodes[node].second;
        nodes[node].first = 0;
        return total;
    }
    return 0;
}

int main(){
    int n,m;
    cin >> n >> m;
    for(int i=0;i<n;i++) cin >>nodes[i].first;

    int a,b;
    for(int i=0;i<m;i++){
        cin >> a >> b;
        a--; b--;
        graph[a].push_back(b);
        graph[b].push_back(a);
        dim[a]++;
        dim[b]++;
    }

    dfs(0, -1);

    int ans = 0, max_second = 0;
    for(int i=0;i<n;i++){
        ans += nodes[i].first;
        if(nodes[i].first != 0) max_second = max(max_second, nodes[i].second);
    }
    ans += max_second;
    cout << ans << endl;

}
accuracy: 1
time_ms: 50
memory_kb: 19216
final_rank: 6

code_snippet: #include <bits/stdc++.h>
      
#define FOR(i,a,b) for( ll i = (a); i < (ll)(b); i++ )
#define REP(i,n) FOR(i,0,n)
#define YYS(x,arr) for(auto& x:arr)
#define ALL(x) (x).begin(),(x).end()
#define SORT(x) sort( (x).begin(),(x).end() )
#define REVERSE(x) reverse( (x).begin(),(x).end() )
#define UNIQUE(x) (x).erase( unique( ALL( (x) ) ) , (x).end() )
#define PW(x) (1LL<<(x))
#define SZ(x) ((ll)(x).size())
#define SHOW(x) cout << #x << " = " << x << endl
#define SHOWA(x,n) for( int yui = 0; yui < n; yui++ ){ cout << x[yui] << " "; } cout << endl

#define pb emplace_back
#define fi first
#define se second

using namespace std;

typedef long double ld;
typedef long long int ll;
typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<bool> vb;
typedef vector<ld> vd;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<vpl> gr;
typedef vector<vl> ml;
typedef vector<vd> md;
typedef vector<vi> mi;
     
const ll INF = (ll)1e9 + 10;
const ll INFLL = (ll)1e18 + 10;
const ld EPS = 1e-12;
const ll MOD = 1e9+7;
     
template<class T> T &chmin( T &a , const T &b ){ return a = min(a,b); }
template<class T> T &chmax( T &a , const T &b ){ return a = max(a,b); }
template<class T> inline T sq( T a ){ return a * a; }

ll in(){ long long int x; scanf( "%lld" , &x ); return x; }
char yuyushiki[1000010]; string stin(){ scanf( "%s" , yuyushiki ); return yuyushiki; }

// head

struct Bridge{
  vector<vpi> G;
  vb used, isbridge;
  vi ord, low;
  int cnt;
  int n, m;
  void init( int size ){
    n = size;
    m = 0;
    G.assign( n , vpi(0) );
  }
  void add_edge( int a, int b ){
    G[a].pb( b, m );
    G[b].pb( a, m );
    m++;
  }
  void dfs( int x , int p ){
    used[x] = true;
    ord[x] = low[x] = cnt++;
    YYS( w , G[x] ){
      if( !used[w.fi] ){
	dfs( w.fi , x );
	chmin( low[x] , low[w.fi] );
      } else if( w.fi != p ){
	chmin( low[x] , ord[w.fi] );
      }
    }
  }
  vb bridge(){
    used = vb( n , false );
    isbridge = vb( m , false );
    ord = low = vi( n , 0 );
    cnt = 0;
    REP( i , n ){
      if( !used[i] ){
	dfs( i , -1 );
      }
    }
    REP( i , n ){
      YYS( w , G[i] ){
	if( ord[i] > ord[w.fi] ){
          continue;
        }
	if( ord[i] < low[w.fi] ){
          isbridge[w.se] = true;
        }
      }
    }
    return isbridge;
  }
};

Bridge bridge;

int n, m;

int a[100010];

vpi G[100010];

vb br;

int ans, ma;

bool used[100010];

int cnt;
void dfs2( int x , vi &nex , int &cur ){
  cnt++;
  used[x] = true;
  cur += a[x];
  YYS( w , G[x] ){
    if( used[w.fi] ){
      continue;
    }
    if( br[w.se] ){
      nex.pb( w.fi );
    } else {
      dfs2( w.fi , nex , cur );
    }
  }
}

pair<bool,int> dfs( int x ){
  vi nex(0);
  cnt = 0;
  int cur = 0;
  dfs2( x , nex , cur );
  bool f = ( x == 0 );
  if( cnt > 1 ){
    f = true;
  }
  vector<pair<bool,int> > res(0);
  YYS( w , nex ){
    res.pb( dfs( w ) );
  }
  YYS( w , res ){
    if( w.fi ){
      f = true;
    }
  }
  int cma = 0;
  YYS( w , res ){
    chmax( cma , w.se );
  }
  if( f ){
    ans += cur;
    cur = 0;
    chmax( ma , cma );
  } else {
    cur += cma;
  }
  return make_pair( f , cur );
}

int main(){

  n = in();
  m = in();
  bridge.init( n );
  REP( i , n ){
    a[i] = in();
  }
  REP( i , m ){
    int x = in() - 1;
    int y = in() - 1;
    G[x].pb( y , i );
    G[y].pb( x , i );
    bridge.add_edge( x , y );
  }

  br = bridge.bridge();

  dfs( 0 );

  printf( "%d\n" , ans + ma );
  
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 29296
final_rank: 8

code_snippet: #include <bits/stdc++.h>
      
#define FOR(i,a,b) for( ll i = (a); i < (ll)(b); i++ )
#define REP(i,n) FOR(i,0,n)
#define YYS(x,arr) for(auto& x:arr)
#define ALL(x) (x).begin(),(x).end()
#define SORT(x) sort( (x).begin(),(x).end() )
#define REVERSE(x) reverse( (x).begin(),(x).end() )
#define UNIQUE(x) (x).erase( unique( ALL( (x) ) ) , (x).end() )
#define PW(x) (1LL<<(x))
#define SZ(x) ((ll)(x).size())
#define SHOW(x) cout << #x << " = " << x << endl
#define SHOWA(x,n) for( int yui = 0; yui < n; yui++ ){ cout << x[yui] << " "; } cout << endl

#define pb emplace_back
#define fi first
#define se second

using namespace std;

typedef long double ld;
typedef long long int ll;
typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<bool> vb;
typedef vector<ld> vd;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<vpl> gr;
typedef vector<vl> ml;
typedef vector<vd> md;
typedef vector<vi> mi;
     
const ll INF = (ll)1e9 + 10;
const ll INFLL = (ll)1e18 + 10;
const ld EPS = 1e-12;
const ll MOD = 1e9+7;
     
template<class T> T &chmin( T &a , const T &b ){ return a = min(a,b); }
template<class T> T &chmax( T &a , const T &b ){ return a = max(a,b); }
template<class T> inline T sq( T a ){ return a * a; }

ll in(){ long long int x; scanf( "%lld" , &x ); return x; }
char yuyushiki[1000010]; string stin(){ scanf( "%s" , yuyushiki ); return yuyushiki; }

// head


struct Bridge{
  vector<vpi> G;
  vb used, isbridge;
  vi ord, low;
  int cnt;
  int n, m;
  void init( int size ){
    n = size;
    m = 0;
    G.assign( n , vpi(0) );
  }
  void add_edge( int a, int b ){
    G[a].pb( b, m );
    G[b].pb( a, m );
    m++;
  }
  void dfs( int x , int p ){
    used[x] = true;
    ord[x] = low[x] = cnt++;
    YYS( w , G[x] ){
      if( !used[w.fi] ){
	dfs( w.fi , x );
	chmin( low[x] , low[w.fi] );
      } else if( w.fi != p ){
	chmin( low[x] , ord[w.fi] );
      }
    }
  }
  vb bridge(){
    used = vb( n , false );
    isbridge = vb( m , false );
    ord = low = vi( n , 0 );
    cnt = 0;
    REP( i , n ){
      if( !used[i] ){
	dfs( i , -1 );
      }
    }
    REP( i , n ){
      YYS( w , G[i] ){
	if( ord[i] > ord[w.fi] ){
          continue;
        }
	if( ord[i] < low[w.fi] ){
          isbridge[w.se] = true;
        }
      }
    }
    return isbridge;
  }
};

Bridge bridge;

int n, m;

int a[100010];

vpi G[100010];

vb br;

int ans;

bool used[100010];

void dfs2( int x , vi &nex , int &cur ){
  used[x] = true;
  cur += a[x];
  YYS( w , G[x] ){
    if( used[w.fi] ){
      continue;
    }
    if( br[w.se] ){
      nex.pb( w.fi );
    } else {
      dfs2( w.fi , nex , cur );
    }
  }
}

void dfs( int x , int cur ){
  vi nex(0);
  dfs2( x , nex , cur );
  chmax( ans , cur );
  YYS( w , nex ){
    dfs( w , cur );
  }
}

int main(){

  n = in();
  m = in();
  bridge.init( n );
  REP( i , n ){
    a[i] = in();
  }
  REP( i , m ){
    int x = in() - 1;
    int y = in() - 1;
    G[x].pb( y , i );
    G[y].pb( x , i );
    bridge.add_edge( x , y );
  }

  br = bridge.bridge();

  dfs( 0 , 0 );

  printf( "%d\n" , ans );
  
  return 0;
}
accuracy: 0.5238095238095238
time_ms: 30
memory_kb: 26216
final_rank: 11

code_snippet: #include <bits/stdc++.h>
      
#define FOR(i,a,b) for( ll i = (a); i < (ll)(b); i++ )
#define REP(i,n) FOR(i,0,n)
#define YYS(x,arr) for(auto& x:arr)
#define ALL(x) (x).begin(),(x).end()
#define SORT(x) sort( (x).begin(),(x).end() )
#define REVERSE(x) reverse( (x).begin(),(x).end() )
#define UNIQUE(x) (x).erase( unique( ALL( (x) ) ) , (x).end() )
#define PW(x) (1LL<<(x))
#define SZ(x) ((ll)(x).size())
#define SHOW(x) cout << #x << " = " << x << endl
#define SHOWA(x,n) for( int yui = 0; yui < n; yui++ ){ cout << x[yui] << " "; } cout << endl

#define pb emplace_back
#define fi first
#define se second

using namespace std;

typedef long double ld;
typedef long long int ll;
typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<bool> vb;
typedef vector<ld> vd;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<vpl> gr;
typedef vector<vl> ml;
typedef vector<vd> md;
typedef vector<vi> mi;
     
const ll INF = (ll)1e9 + 10;
const ll INFLL = (ll)1e18 + 10;
const ld EPS = 1e-12;
const ll MOD = 1e9+7;
     
template<class T> T &chmin( T &a , const T &b ){ return a = min(a,b); }
template<class T> T &chmax( T &a , const T &b ){ return a = max(a,b); }
template<class T> inline T sq( T a ){ return a * a; }

ll in(){ long long int x; scanf( "%lld" , &x ); return x; }
char yuyushiki[1000010]; string stin(){ scanf( "%s" , yuyushiki ); return yuyushiki; }

// head

struct Bridge{
  vector<vpi> G;
  vb used, isbridge;
  vi ord, low;
  int cnt;
  int n, m;
  void init( int size ){
    n = size;
    m = 0;
    G.assign( n , vpi(0) );
  }
  void add_edge( int a, int b ){
    G[a].pb( b, m );
    G[b].pb( a, m );
    m++;
  }
  void dfs( int x , int p ){
    used[x] = true;
    ord[x] = low[x] = cnt++;
    YYS( w , G[x] ){
      if( !used[w.fi] ){
	dfs( w.fi , x );
	chmin( low[x] , low[w.fi] );
      } else if( w.fi != p ){
	chmin( low[x] , ord[w.fi] );
      }
    }
  }
  vb bridge(){
    used = isbridge = vb( n , false );
    ord = low = vi( n , 0 );
    cnt = 0;
    REP( i , n ){
      if( !used[i] ){
	dfs( i , -1 );
      }
    }
    REP( i , n ){
      YYS( w , G[i] ){
	if( ord[i] > ord[w.fi] ) continue;
	if( ord[i] < low[w.fi] ) isbridge[w.se] = true;
      }
    }
    return isbridge;
  }
};

Bridge bridge;

int n, m;

int a[100010];

vpi G[100010];

vb br;

int ans;

bool used[100010];

void dfs2( int x , vi &nex , int &cur ){
  used[x] = true;
  cur += a[x];
  YYS( w , G[x] ){
    if( used[w.fi] ){
      continue;
    }
    if( br[w.se] ){
      nex.pb( w.fi );
    } else {
      dfs2( w.fi , nex , cur );
    }
  }
}

void dfs( int x , int cur ){
  vi nex(0);
  dfs2( x , nex , cur );
  chmax( ans , cur );
  YYS( w , nex ){
    dfs( w , cur );
  }
}

int main(){

  n = in();
  m = in();
  bridge.init( n );
  REP( i , n ){
    a[i] = in();
  }
  REP( i , m ){
    int x = in() - 1;
    int y = in() - 1;
    G[x].pb( y , i );
    G[y].pb( x , i );
    bridge.add_edge( x , y );
  }

  br = bridge.bridge();

  dfs( 0 , 0 );

  printf( "%d\n" , ans );
  
  return 0;
}
accuracy: 0.047619047619047616
time_ms: 10
memory_kb: 9572
final_rank: 20

code_snippet: // AOJ #2712
// Escape 2025.2.11

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

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0, c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(int n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

const int MAX_N = 100001;
typedef pair<int,int> P;
vector<int> adj[MAX_N];
vector<int> cycleNodes;
bool used[MAX_N];
 
bool dfs(int x, int parent) {
    if(used[x]) return true;
    used[x] = true;
    bool foundCycle = false;
    for (int nxt : adj[x]) {
        if(nxt == parent) continue;
        foundCycle |= dfs(nxt, x);
    }
    if(foundCycle) cycleNodes.push_back(x);
    return foundCycle;
}
 
int main() {
    int n = Cin(), m = Cin();
    vector<int> weight(n);
    for (int i = 0; i < n; i++) weight[i] = Cin();

    for (int i = 0; i < m; i++){
        int u = Cin()-1, v = Cin()-1;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(0, -1);
 
    vector<int> d(n, -1);
    int cycleSum = 0;
    int additionalMax = 0;
    priority_queue<P, vector<P>, greater<P>> pq;
 
    for (int v : cycleNodes) {
        if(d[v] == -1){
            d[v] = 0;
            pq.push({0, v});
            cycleSum += weight[v];
        }
    }
    if(pq.empty()){
        d[0] = weight[0];
        pq.push({weight[0], 0});
    }
 
    while(!pq.empty()){
        P cur = pq.top();
        pq.pop();
        int curScore = cur.first;
        int curVertex = cur.second;
        if(d[curVertex] != curScore) continue;
        for (int nxt : adj[curVertex]){
            if(d[nxt] == -1){
                d[nxt] = curScore + weight[nxt];
                pq.push({d[nxt], nxt});
            }
        }
    }
    for (int i = 0; i < n; i++)
        additionalMax = max(additionalMax, d[i]);
    Cout(cycleSum + additionalMax);
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 16968
final_rank: 2

code_snippet: // AOJ #2712
// Escape 2025.2.11

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll NEG_INF = -1000000000000000LL;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0, c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(ll n) { // 整数の表示（出力）
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

struct Edge { int u, v; };
 
int main() {
    int n = Cin(), m = Cin();
    vector<int> w(n);
    for (int i = 0; i < n; i++) w[i] = Cin();
 
    vector<vector<pair<int,int>>> graph(n);
    vector<Edge> edges;
    edges.reserve(m);
    for (int i = 0; i < m; i++){
        int u = Cin()-1, v = Cin()-1;
        edges.push_back({u, v});
        graph[u].push_back({v, i});
        graph[v].push_back({u, i});
    }
 
    vector<int> tin(n, -1), low(n, -1);
    vector<bool> isBridge(m, false);
    int timer = 0;
    function<void(int, int)> dfsBridge = [&](int v, int parentEdge) {
        tin[v] = low[v] = timer++;
        for (auto &p : graph[v]){
            int to = p.first, id = p.second;
            if(id == parentEdge) continue;
            if(tin[to] == -1){
                dfsBridge(to, id);
                low[v] = min(low[v], low[to]);
                if(low[to] > tin[v]) isBridge[id] = true;
            } else low[v] = min(low[v], tin[to]);
        }
    };
    for (int i = 0; i < n; i++){
        if(tin[i] == -1) dfsBridge(i, -1);
    }
 
    vector<int> comp(n, -1);
    int compCount = 0;
    vector<ll> compWeight; 
    vector<int> compSize;
    compWeight.resize(n, 0);
    compSize.resize(n, 0);
    function<void(int,int)> dfsComp = [&](int v, int cid) {
        comp[v] = cid;
        compWeight[cid] += w[v];
        compSize[cid]++;
        for(auto &p : graph[v]){
            int to = p.first, id = p.second;
            if(isBridge[id]) continue;
            if(comp[to] == -1) dfsComp(to, cid);
        }
    };
    for (int i = 0; i < n; i++){
        if(comp[i] == -1){
            dfsComp(i, compCount);
            compCount++;
        }
    }
    compWeight.resize(compCount);
    compSize.resize(compCount);
 
    vector<bool> compSafe(compCount, false);
    for (int i = 0; i < compCount; i++)
        compSafe[i] = (compSize[i] >= 2);
 
    vector<vector<int>> tree(compCount);
    for (int i = 0; i < m; i++){
        if(!isBridge[i]) continue;
        int u = edges[i].u, v = edges[i].v;
        int cu = comp[u], cv = comp[v];
        tree[cu].push_back(cv);
        tree[cv].push_back(cu);
    }
 
    vector<pair<ll,ll>> dp(compCount, {0,0});
    int root = comp[0];
    vector<bool> visited(compCount, false);
    function<void(int,int)> dfsTree = [&](int v, int parent) {
        visited[v] = true;
        for (int u : tree[v]){
            if(u == parent) continue;
            dfsTree(u, v);
        }
        bool isRoot = (v == root);
        bool safe = (isRoot || compSafe[v]);
 
        if(safe){
            ll closed_sum = 0;
            ll extraCandidate = 0;
            for (int u : tree[v]){
                if(u == parent) continue;
                if(compSafe[u]){
                    ll branch_closed = compWeight[u] + dp[u].first;
                    if(branch_closed < 0) branch_closed = 0;
                    closed_sum += branch_closed;
                    ll branch_open = compWeight[u] + dp[u].second;
                    extraCandidate = max(extraCandidate, branch_open - branch_closed);
                } else {
                    ll branch_open = compWeight[u] + dp[u].second;
                    extraCandidate = max(extraCandidate, branch_open);
                }
            }
            dp[v].first = closed_sum;
            dp[v].second = closed_sum + extraCandidate;
        } else {
            ll bestOpen = 0;
            for (int u : tree[v]){
                if(u == parent) continue;
                ll branch_open = compWeight[u] + dp[u].second;
                bestOpen = max(bestOpen, branch_open);
            }
            dp[v].first = NEG_INF;
            dp[v].second = bestOpen;
        }
    };
 
    dfsTree(root, -1);
    ll ans = compWeight[root] + dp[root].second;
    Cout(ans);
    return 0;
}
accuracy: 0.5238095238095238
time_ms: 20
memory_kb: 29900
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

void chmin(int &a, int b) { a = min(a, b); }
struct LowLink {
   public:
   vector<vector<int>> g;
   vector<int> ord, low;
   vector<int> articulation;
   vector<bool> visited;
   vector<pair<int, int>> bridge;

   void dfs(int cur, int pre, int& k) {
      visited[cur] = true;
      ord[cur] = low[cur] = k++;
      bool isArticulation = false;
      int cnt = 0;
      for(auto to : g[cur]) {
         if(!visited[to]) {
            cnt++;
            dfs(to, cur, k);
            chmin(low[cur], low[to]);
            if(pre != -1 && ord[cur] <= low[to]) isArticulation = true;
            if(ord[cur] < low[to]) bridge.emplace_back(min(cur, to), max(cur, to));
         } else if(to != pre) chmin(low[cur], ord[to]);
      }
      if(pre == -1 && cnt > 1) isArticulation = true;
      if(isArticulation) articulation.push_back(cur);
   }

   void build(const vector<vector<int>>& g) {
      int n = g.size();
      this->g = g;
      ord.assign(n, -1);
      low.assign(n, -1);
      visited.assign(n, false);
      int k = 0;
      for(int i = 0; i < n; i++)
         if(!visited[i]) dfs(i, -1, k);
   }
   LowLink(const vector<vector<int>>& g) { build(g); }

   vector<int>& getArticulations() { return articulation; }
   vector<pair<int, int>>& getBridges() { return bridge; }
   vector<int>& getOrd() { return ord; }
   vector<int>& getLowlink() { return low; }
};

struct UnionFind {
    vector<int> par;
    UnionFind(int n) :par(n, -1) { }
    void init(int n) { par.assign(n, -1); }
    int root(int x) {
        if (par[x] < 0) return x;
        else return par[x] = root(par[x]);
    }
    bool connect(int x, int y) {
        x = root(x); y = root(y);
        if (x == y) return false;
        if (par[x] > par[y]) swap(x, y);
        par[x] += par[y];
        par[y] = x;
        return true;
    }
    int size(int x) {
        return -par[root(x)];
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    int n, m;
    cin >> n >> m;
    vector<ll> w(n);
    rep(i, n) cin >> w[i];
    UnionFind uf(n);
    vector<vector<int>> v(n);
    vector<pair<int, int>> edges;
    rep(i, m) {
        int a, b;
        cin >> a >> b;
        a --; b --;
        if(a > b) swap(a, b);
        edges.push_back({a, b});
        v[a].pb(b);
        v[b].pb(a);
    }
    LowLink link(v);
    auto bs = link.getBridges();
    set<pair<int, int>> st;
    for(auto [x, y] : bs) {
        st.insert({min(x, y), max(x, y)});
    }
    foa(e, edges) if(!st.count(e)) uf.connect(e.first, e.second);
    

    vector<ll> c(n, 0);
    vector<vector<int>> g(n);
    foa(e, edges) if(st.count(e)) {
        int x = uf.root(e.first);
        int y = uf.root(e.second);
        g[x].pb(y);
        g[y].pb(x);
    }
    int r = uf.root(0);
    vector<int> cnt(n, 0);
    rep(i, n) c[uf.root(i)] += w[i];
    rep(i, n) cnt[uf.root(i)] ++;
    cnt[r] ++;

    ll ans = 0;
    auto dfs = [&](auto dfs, int now, int p) -> pair<ll, bool> { 
        bool f = cnt[now] >= 2;
        ll sum1 = c[now], sum2 = c[now];
        foa(e, g[now]) {
            if(e == p) continue;
            auto [r1, r2] = dfs(dfs, e, now);
            f |= r2;
            if(r2) {
                sum1 += r1;
            } else {
                sum2 = max(c[now] + r1, sum2);
            }
        }
        if(!f) ans = max(ans, sum2);
        if(f) return {sum1, true};
        return {sum2, false};
    };
    cout << dfs(dfs, r, -1).first + ans << endl;
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 42568
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

void chmin(int &a, int b) { a = min(a, b); }
struct LowLink {
   public:
   vector<vector<int>> g;
   vector<int> ord, low;
   vector<int> articulation;
   vector<bool> visited;
   vector<pair<int, int>> bridge;

   void dfs(int cur, int pre, int& k) {
      visited[cur] = true;
      ord[cur] = low[cur] = k++;
      bool isArticulation = false;
      int cnt = 0;
      for(auto to : g[cur]) {
         if(!visited[to]) {
            cnt++;
            dfs(to, cur, k);
            chmin(low[cur], low[to]);
            if(pre != -1 && ord[cur] <= low[to]) isArticulation = true;
            if(ord[cur] < low[to]) bridge.emplace_back(min(cur, to), max(cur, to));
         } else if(to != pre) chmin(low[cur], ord[to]);
      }
      if(pre == -1 && cnt > 1) isArticulation = true;
      if(isArticulation) articulation.push_back(cur);
   }

   void build(const vector<vector<int>>& g) {
      int n = g.size();
      this->g = g;
      ord.assign(n, -1);
      low.assign(n, -1);
      visited.assign(n, false);
      int k = 0;
      for(int i = 0; i < n; i++)
         if(!visited[i]) dfs(i, -1, k);
   }
   LowLink(const vector<vector<int>>& g) { build(g); }

   vector<int>& getArticulations() { return articulation; }
   vector<pair<int, int>>& getBridges() { return bridge; }
   vector<int>& getOrd() { return ord; }
   vector<int>& getLowlink() { return low; }
};

struct UnionFind {
    vector<int> par;
    UnionFind(int n) :par(n, -1) { }
    void init(int n) { par.assign(n, -1); }
    int root(int x) {
        if (par[x] < 0) return x;
        else return par[x] = root(par[x]);
    }
    bool connect(int x, int y) {
        x = root(x); y = root(y);
        if (x == y) return false;
        if (par[x] > par[y]) swap(x, y);
        par[x] += par[y];
        par[y] = x;
        return true;
    }
    int size(int x) {
        return -par[root(x)];
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    int n, m;
    cin >> n >> m;
    vector<ll> w(n);
    rep(i, n) cin >> w[i];
    UnionFind uf(n);
    vector<vector<int>> v(n);
    vector<pair<int, int>> edges;
    rep(i, m) {
        int a, b;
        cin >> a >> b;
        a --; b --;
        if(a > b) swap(a, b);
        edges.push_back({a, b});
        v[a].pb(b);
        v[b].pb(a);
    }
    LowLink link(v);
    auto bs = link.getBridges();
    set<pair<int, int>> st;
    for(auto [x, y] : bs) {
        st.insert({min(x, y), max(x, y)});
    }
    foa(e, edges) if(!st.count(e)) uf.connect(e.first, e.second);
    

    vector<ll> c(n, 0);
    vector<vector<int>> g(n);
    foa(e, edges) if(st.count(e)) {
        int x = uf.root(e.first);
        int y = uf.root(e.second);
        g[x].pb(y);
        g[y].pb(x);
    }
    int r = uf.root(0);
    rep(i, n) c[uf.root(i)] += w[i];
    auto dfs = [&](auto dfs, int now, int p) -> ll {
        ll ret = 0;
        foa(e, g[now]) {
            if(e == p) continue;
            // cout << now << " " << e << endl;
            ret = max(ret, dfs(dfs, e, now));
        }
        ret += c[now];
        return ret;
    };
    cout << dfs(dfs, r, -1) << endl;
    return 0;
}
accuracy: 0.5238095238095238
time_ms: 60
memory_kb: 39112
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

void chmin(int &a, int b) { a = min(a, b); }
struct LowLink {
   public:
   vector<vector<int>> g;
   vector<int> ord, low;
   vector<int> articulation;
   vector<bool> visited;
   vector<pair<int, int>> bridge;

   void dfs(int cur, int pre, int& k) {
      visited[cur] = true;
      ord[cur] = low[cur] = k++;
      bool isArticulation = false;
      int cnt = 0;
      for(auto to : g[cur]) {
         if(!visited[to]) {
            cnt++;
            dfs(to, cur, k);
            chmin(low[cur], low[to]);
            if(pre != -1 && ord[cur] <= low[to]) isArticulation = true;
            if(ord[cur] < low[to]) bridge.emplace_back(min(cur, to), max(cur, to));
         } else if(to != pre) chmin(low[cur], ord[to]);
      }
      if(pre == -1 && cnt > 1) isArticulation = true;
      if(isArticulation) articulation.push_back(cur);
   }

   void build(const vector<vector<int>>& g) {
      int n = g.size();
      this->g = g;
      ord.assign(n, -1);
      low.assign(n, -1);
      visited.assign(n, false);
      int k = 0;
      for(int i = 0; i < n; i++)
         if(!visited[i]) dfs(i, -1, k);
   }
   LowLink(const vector<vector<int>>& g) { build(g); }

   vector<int>& getArticulations() { return articulation; }
   vector<pair<int, int>>& getBridges() { return bridge; }
   vector<int>& getOrd() { return ord; }
   vector<int>& getLowlink() { return low; }
};

struct UnionFind {
    vector<int> par;
    UnionFind(int n) :par(n, -1) { }
    void init(int n) { par.assign(n, -1); }
    int root(int x) {
        if (par[x] < 0) return x;
        else return par[x] = root(par[x]);
    }
    bool connect(int x, int y) {
        x = root(x); y = root(y);
        if (x == y) return false;
        if (par[x] > par[y]) swap(x, y);
        par[x] += par[y];
        par[y] = x;
        return true;
    }
    int size(int x) {
        return -par[root(x)];
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    int n, m;
    cin >> n >> m;
    vector<ll> w(n);
    rep(i, n) cin >> w[i];
    UnionFind uf(n);
    vector<vector<int>> v(n);
    vector<pair<int, int>> edges;
    rep(i, m) {
        int a, b;
        cin >> a >> b;
        a --; b --;
        if(a > b) swap(a, b);
        edges.push_back({a, b});
        v[a].pb(b);
        v[b].pb(a);
    }
    LowLink link(v);
    auto bs = link.getBridges();
    set<pair<int, int>> st;
    for(auto [x, y] : bs) {
        st.insert({x, y});
    }
    foa(e, edges) if(!st.count(e)) uf.connect(e.first, e.second);
    

    vector<ll> c(n, 0);
    vector<vector<int>> g(n);
    foa(e, edges) if(st.count(e)) {
        int x = uf.root(e.first);
        int y = uf.root(e.second);
        g[x].pb(y);
        g[y].pb(x);
    }
    int r = uf.root(0);
    rep(i, n) c[uf.root(i)] += w[i];
    auto dfs = [&](auto dfs, int now, int p) -> ll {
        ll ret = 0;
        foa(e, g[now]) {
            if(e == p) continue;
            // cout << now << " " << e << endl;
            ret = max(ret, dfs(dfs, e, now));
        }
        ret += c[now];
        return ret;
    };
    cout << dfs(dfs, r, -1) << endl;
    return 0;
}
accuracy: 0.5238095238095238
time_ms: 60
memory_kb: 38992
final_rank: 13

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
    int N, M;
    cin >> N >> M;
    vector<int> A(N);
    rep(i,0,N) cin >> A[i];
    vector<vector<int>> G(N);
    rep(i,0,M) {
        int U, V;
        cin >> U >> V;
        U--, V--;
        G[U].push_back(V);
        G[V].push_back(U);
    }
    vector<int> Deg(N);
    rep(i,0,N) Deg[i] = G[i].size();
    vector<bool> used(N,false);
    queue<int> Q;
    rep(i,0,N) {
        if (Deg[i] == 1 && i != 0) Q.push(i);
    }
    while(!Q.empty()) {
        int P = Q.front();
        Q.pop();
        used[P] = true;
        for (int NP : G[P]) {
            if (used[NP]) continue;
            Deg[NP]--;
            if (Deg[NP] == 1 && NP != 0) Q.push(NP);
        }
    }
    vector<ll> DP(N,INF);
    ll ANS = 0;
    rep(i,0,N) {
        if (!used[i]) {
            DP[i] = 0;
            Q.push(i);
            ANS += A[i];
        }
    }
    while(!Q.empty()) {
        int P = Q.front();
        Q.pop();
        for (int NP : G[P]) {
            if (chmin(DP[NP],DP[P]+A[NP])) {
                Q.push(NP);
            }
        }
    }
    ll MAX = 0;
    rep(i,0,N) chmax(MAX,DP[i]);
    cout << ANS + MAX << endl;
}
accuracy: 1
time_ms: 50
memory_kb: 10788
final_rank: 3

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

int main() {
    int n = in(), m = in();
    vector<int> w = in(n);
    vector<vector<int>> g(n);
    vector<int> deg(n, 0);
    for(int i : rep(m)) {
        int u = in(), v = in(); u--, v--;
        g[u].push_back(v);
        g[v].push_back(u);
        deg[u]++, deg[v]++;
    }

    queue<int> q;
    for(int v : rep(n)) if(deg[v] == 1) q.push(v);

    vector<int> vis(n, 0);
    vector<vector<int>> forest(n);
    while(not q.empty()) {
        int v = q.front(); q.pop();
        vis[v] = true;
        for(int to : g[v]) {
            if(--deg[to] == 1) q.push(to);
        }
    }

    vector<int> is_r(n, 0), roots;
    for(int u : rep(n)) if(vis[u]) {
        bool is_root = false;
        for(int v : g[u]) {
            if(vis[v]) {
                forest[u].push_back(v);
            } else {
                is_root = true;
            }
        }
        if(is_root) {
            is_r[u] = is_root;
            roots.push_back(u);
        }
    }

    auto dfs = [&](auto self, int v, int p) -> int {
        int max = 0;
        for(int to : forest[v]) {
            if(to != p) {
                chmax(max, self(self, to, v));
            }
        }
        return max + w[v];
    };

    bool is_tree = [&] {
        for(int v : rep(n)) if(not vis[v]) return false;
        return true;
    }();
    if(is_tree) return print(dfs(dfs, 0, -1));

    bool start_tree = vis[0];
    int prev = 0;

    if(start_tree) {
        vector<int> path;
        auto get_path = [&](auto self, int v, int p) -> bool {
            path.push_back(v);
            if(is_r[v]) {
                for(int x : path) {
                    prev += w[x];
                    w[x] = 0;
                }
                return true;
            }
            for(int to : forest[v]) if(to != p) {
                if(self(self, to, v)) return true;
            }
            return false;
        };
        get_path(get_path, 0, -1);
    }

    int path_max = 0;
    for(int r : roots) chmax(path_max, dfs(dfs, r, -1));
    int sum = 0;
    for(int v : rep(n)) if(not vis[v]) sum += w[v];
    print(prev + sum + path_max);
}
accuracy: 1
time_ms: 30
memory_kb: 24988
final_rank: 4

code_snippet: #include <bits/stdc++.h>




namespace zawa {

using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;

using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;

using usize = std::size_t;

} // namespace zawa


namespace zawa {

void SetFastIO() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
}

void SetPrecision(u32 dig) {
    std::cout << std::fixed << std::setprecision(dig);
}

} // namespace zawa



namespace zawa {

class Lowlink {
private:
    static constexpr u32 INVALID{static_cast<u32>(-1)};
    usize n_{}, m_{};
    std::vector<std::vector<std::pair<u32, u32>>> g_;
    std::vector<std::pair<u32, u32>> e_;
    std::vector<u32> in_, low_;
    std::vector<u32> articulation_;
    std::vector<bool> bridge_;

    void dfs(u32 v, u32 p, u32& t) {
        low_[v] = in_[v] = t++;
        u32 deg{}; 
        for (const auto& [x, i] : g_[v]) {
            if (in_[x] == INVALID) {
                deg++;
                dfs(x, v, t);
                low_[v] = std::min(low_[v], low_[x]);
                if (p != INVALID and low_[x] >= in_[v]) {
                    articulation_[v]++;
                }
                if (low_[x] > in_[v]) {
                    bridge_[i] = true;
                }
            }
            else if (x != p) {
                low_[v] = std::min(low_[v], in_[x]);
            }
        }
        if (p == INVALID) {
            articulation_[v] = deg;
        }
    }

public:
    constexpr usize size() const noexcept {
        return n_;
    }
    constexpr usize edgeSize() const noexcept {
        return m_;
    }

    Lowlink() = default;
    Lowlink(usize n) 
        : n_{n}, m_{}, g_(n), in_(n, INVALID), low_(n), articulation_(n, u32{1}), bridge_{} {
        g_.shrink_to_fit();
        in_.shrink_to_fit();
        low_.shrink_to_fit();
        articulation_.shrink_to_fit();
    }
    
    usize addEdge(u32 u, u32 v) {
        usize res{m_++};
        e_.emplace_back(u, v);
        g_[u].emplace_back(v, res);
        g_[v].emplace_back(u, res);
        return res;
    }

    const std::vector<std::pair<u32, u32>>& operator[](u32 v) const noexcept {
        assert(v < size());
        return g_[v];
    }
    const std::pair<u32, u32>& edge(u32 i) const noexcept {
        assert(i < edgeSize());
        return e_[i];
    }

    void build() {
        bridge_.resize(edgeSize());
        u32 t{};
        for (u32 v{} ; v < size() ; v++) if (in_[v] == INVALID) {
            dfs(v, INVALID, t);
        }
    }

    bool articular(u32 v) const noexcept {
        assert(v < size());
        return articulation_[v] > 1u;
    }
    u32 cut(u32 v) const noexcept {
        assert(v < size());
        return articulation_[v];
    }
    bool bridge(u32 i) const noexcept {
        assert(i < edgeSize());
        return bridge_[i];
    }
};

} // namespace zawa
using namespace zawa;

int main() {
    SetFastIO();

    int n, m; std::cin >> n >> m;
    std::vector<int> w(n);
    for (auto& x : w) std::cin >> x;
    Lowlink g(n);
    for (int i{} ; i < m ; i++) {
        int a, b; std::cin >> a >> b;
        a--; b--;
        g.addEdge(a, b);
    }
    g.build();
    std::vector<int> col(n, -1);
    int c{};
    auto dfs{[&](auto dfs, int v) -> void {
        assert(col[v] == -1);
        col[v] = c;
        for (auto [x, i] : g[v]) {
            if (col[x] != -1) continue;
            if (g.bridge(i)) continue;
            dfs(dfs, x);
        }
    }};
    for (int i{} ; i < n ; i++) if (col[i] == -1) {
        dfs(dfs, i);
        c++;
    }
    std::vector<std::vector<int>> tree(c);
    for (int i{} ; i < m ; i++) if (g.bridge(i)) {
        auto [u, v]{g.edge(i)};
        assert(col[u] != -1);
        assert(col[v] != -1);
        u = col[u];
        v = col[v];
        assert(u != v);
        tree[u].emplace_back(v);
        tree[v].emplace_back(u);
    }
    std::vector<int> cnt(c), sum(c);
    for (int i{} ; i < n ; i++) {
        cnt[col[i]]++;
        sum[col[i]] += w[i];
    }
    using tuple = std::tuple<int, int, bool>;
    auto rec{[&](auto rec, int v, int p) -> tuple {
        tuple res{0, 0, false};  
        for (auto x : tree[v]) if (x != p) {
            auto [a, b, ok]{rec(rec, x, v)};
            // std::cout << x << ' ' << a << ' ' << b << ' ' << ok << std::endl;
            std::get<0>(res) += a;
            std::get<1>(res) = std::max(std::get<1>(res), b);
            std::get<2>(res) |= ok;
        }
        if (cnt[v] > 1) std::get<2>(res) = true;
        if (std::get<2>(res)) {
            std::get<0>(res) += sum[v];
        }
        else {
            std::get<1>(res) += sum[v];
        }
        return res;
    }};
    auto [a, b, _]{rec(rec, col[0], -1)};
    int ans{a + b};
    std::cout << ans << '\n';
}
accuracy: 1
time_ms: 30
memory_kb: 29880
final_rank: 5

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
// #include<atcoder/mincostflow>
using namespace std;
// using namespace atcoder;

void solve(){
	int n, m;
	cin >> n >> m;
	vector<int> W(n);
	int ans = 0;
	for(int i = 0; i < n; i++){
		cin >> W[i];
		ans += W[i];
	}

	vector<vector<int>> edges(n, vector<int>());
	vector<int> deg(n, 0);
	int u, v;
	for(int i = 0; i < m; i++){
		cin >> u >> v;
		u--; v--;
		deg[u]++;
		deg[v]++;
		edges[u].push_back(v);
		edges[v].push_back(u);
	}
	stack<int> st;
	for(int i = 1; i < n; i++){
		if(deg[i] == 1){
			st.push(i);
		}
	}
	vector<int> minus(n, 0);
	while(!st.empty()){
		int pos = st.top();
		st.pop();
		ans -= W[pos];
		for(auto npos:edges[pos]){
			if(deg[npos] == 1) minus[pos] = max(minus[pos], minus[npos]);
			else{
				deg[npos]--;
				if(deg[npos] == 1 && npos != 0) st.push(npos);
			}
		}
		minus[pos] += W[pos];
	}
	int ma = 0;
	for(auto w:minus) ma = max(ma, w);
	ans += ma;
	cout << ans << "\n";
}

int main(){
	cin.tie(0)->sync_with_stdio(0);
	int t;
	t = 1;
	// cin >> t;
	while(t--) solve();
}
accuracy: 1
time_ms: 20
memory_kb: 10376
final_rank: 1

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
// #include<atcoder/mincostflow>
using namespace std;
// using namespace atcoder;

void solve(){
	int n, m;
	cin >> n >> m;
	vector<int> W(n);
	int ans = 0;
	for(int i = 0; i < n; i++){
		cin >> W[i];
		ans += W[i];
	}

	vector<vector<int>> edges(n, vector<int>());
	vector<int> deg(n, 0);
	int u, v;
	for(int i = 0; i < m; i++){
		cin >> u >> v;
		u--; v--;
		deg[u]++;
		deg[v]++;
		edges[u].push_back(v);
		edges[v].push_back(u);
	}
	stack<int> st;
	for(int i = 1; i < n; i++){
		if(deg[i] == 1){
			st.push(i);
		}
	}
	vector<int> minus(n, 0);
	while(!st.empty()){
		int pos = st.top();
		st.pop();
		ans -= W[pos];
		for(auto npos:edges[pos]){
			if(deg[npos] == 1) minus[pos] = max(minus[pos], minus[npos]);
			else{
				deg[npos]--;
				if(deg[npos] == 1 && pos != 0) st.push(npos);
			}
		}
		minus[pos] += W[pos];
	}
	int ma = 0;
	for(auto w:minus) ma = max(ma, w);
	ans += ma;
	cout << ans << "\n";
}

int main(){
	cin.tie(0)->sync_with_stdio(0);
	int t;
	t = 1;
	// cin >> t;
	while(t--) solve();
}
accuracy: 0.19047619047619047
time_ms: 20
memory_kb: 9712
final_rank: 15

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
// #include<atcoder/mincostflow>
using namespace std;
// using namespace atcoder;

void solve(){
	int n, m;
	cin >> n >> m;
	vector<int> W(n);
	int ans = 0;
	for(int i = 0; i < n; i++){
		cin >> W[i];
		ans += W[i];
	}

	vector<vector<int>> edges(n, vector<int>());
	vector<int> deg(n, 0);
	int u, v;
	for(int i = 0; i < m; i++){
		cin >> u >> v;
		u--; v--;
		deg[u]++;
		deg[v]++;
		edges[u].push_back(v);
		edges[v].push_back(u);
	}
	stack<int> st;
	for(int i = 1; i < n; i++){
		if(deg[i] == 1) st.push(i);
	}
	vector<int> minus(n, 0);
	while(!st.empty()){
		int pos = st.top();
		st.pop();
		ans -= W[pos];
		minus[pos] += W[pos];
		for(auto npos:edges[pos]){
			if(deg[npos] == 0) minus[pos] += minus[npos];
			else{
				deg[npos]--;
				if(deg[npos] == 0 && pos != 0) st.push(npos);
			}
		}
	}
	int ma = 0;
	for(auto w:minus) ma = max(ma, w);
	ans += ma;
	cout << ans << "\n";
}

int main(){
	cin.tie(0)->sync_with_stdio(0);
	int t;
	t = 1;
	// cin >> t;
	while(t--) solve();
}
accuracy: 0.19047619047619047
time_ms: 20
memory_kb: 9896
final_rank: 16

code_snippet: #include <bits/extc++.h>

using namespace std;

#define rep(i,n) for(int i=0;i<(n);++i)
#define reps(i,s,n) for(int i=(s);i<=(n);++i)
#define all(x) begin(x), end(x)
#define Fixed fixed << setprecision(12)
#define updiv(a,b) (((a) + (b) - 1) / (b))
constexpr int32_t INF  = 0x3f3f3f3f;
constexpr int64_t LINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr int mod = 1e9+7;
// constexpr int mod = 998244353;

template <class Func>
class FixPoint : Func {
public:
    explicit constexpr FixPoint(Func&& f) noexcept : Func(forward<Func>(f)) {}

    template <class... Args>
    constexpr decltype(auto) operator()(Args&&... args) const {
        return Func::operator()(*this, std::forward<Args>(args)...);
    }
};

template <class Func>
static inline constexpr decltype(auto) makeFixPoint(Func&& f) noexcept {
    return FixPoint<Func>{forward<Func>(f)};
}

template <class A, class B> inline bool chmax(A &a, const B &b) { return b > a && (a = b, true); }
template <class A, class B> inline bool chmin(A &a, const B &b) { return b < a && (a = b, true); }

template <class T> using max_heap = priority_queue<T>;
template <class T> using min_heap = priority_queue<T,vector<T>,greater<T> >;
template <class A, class B> using umap = unordered_map<A,B>;
template <class A, class B> using uset = unordered_set<A,B>;

template <class T> using Set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;

template <class T> inline void bye(T x) { cout << x << '\n'; exit(0); }

constexpr int dx[] = {1, 0, -1, 0, 1, 1, -1, -1};
constexpr int dy[] = {0, -1, 0, 1, 1, -1, -1, 1};

template< typename T = int >
struct Edge {
    int from, to;
    T cost;
    int idx;

    Edge() = default;

    Edge(int from, int to, T cost = 1, int idx = -1) : from(from), to(to), cost(cost), idx(idx) {}

    operator int() const { return to; }
};

template< typename T = int >
struct Graph {
    vector< vector< Edge< T > > > g;
    int es;

    Graph() = default;

    explicit Graph(int n) : g(n), es(0) {}

    size_t size() const {
        return g.size();
    }

    void add_directed_edge(int from, int to, T cost = 1) {
        g[from].emplace_back(from, to, cost, es++);
    }

    void add_edge(int from, int to, T cost = 1) {
        g[from].emplace_back(from, to, cost, es);
        g[to].emplace_back(to, from, cost, es++);
    }

    void read(int M, int padding = -1, bool weighted = false, bool directed = false) {
        for(int i = 0; i < M; i++) {
            int a, b;
            cin >> a >> b;
            a += padding;
            b += padding;
            T c = T(1);
            if(weighted) cin >> c;
            if(directed) add_directed_edge(a, b, c);
            else add_edge(a, b, c);
        }
    }

    inline vector< Edge< T > > &operator[](const int &k) {
        return g[k];
    }

    inline const vector< Edge< T > > &operator[](const int &k) const {
        return g[k];
    }
};

template< typename T = int >
using Edges = vector< Edge< T > >;

template< typename T = int >
struct LowLink : Graph< T > {
public:
    using Graph< T >::Graph;
    vector< int > ord, low, articulation;
    vector< Edge< T > > bridge;
    using Graph< T >::g;

    virtual void build() {
        used.assign(g.size(), 0);
        ord.assign(g.size(), 0);
        low.assign(g.size(), 0);
        int k = 0;
        for(int i = 0; i < (int) g.size(); i++) {
            if(!used[i]) k = dfs(i, k, -1);
        }
    }

    explicit LowLink(const Graph< T > &g) : Graph< T >(g) {}

private:
    vector< int > used;

    int dfs(int idx, int k, int par) {
        used[idx] = true;
        ord[idx] = k++;
        low[idx] = ord[idx];
        bool is_articulation = false, beet = false;
        int cnt = 0;
        for(auto &to : g[idx]) {
            if(to == par && !exchange(beet, true)) {
                continue;
            }
            if(!used[to]) {
                ++cnt;
                k = dfs(to, k, idx);
                low[idx] = min(low[idx], low[to]);
                is_articulation |= par >= 0 && low[to] >= ord[idx];
                if(ord[idx] < low[to]) bridge.emplace_back(to);
            } else {
                low[idx] = min(low[idx], ord[to]);
            }
        }
        is_articulation |= par == -1 && cnt > 1;
        if(is_articulation) articulation.push_back(idx);
        return k;
    }
};

template< typename T = int >
struct TwoEdgeConnectedComponents : LowLink< T > {
public:
    using LowLink< T >::LowLink;
    using LowLink< T >::g;
    using LowLink< T >::ord;
    using LowLink< T >::low;
    using LowLink< T >::bridge;

    vector< int > comp;
    Graph< T > tree;
    vector< vector< int > > group;

    int operator[](const int &k) const {
        return comp[k];
    }

    void build() override {
        LowLink< T >::build();
        comp.assign(g.size(), -1);
        int k = 0;
        for(int i = 0; i < (int) comp.size(); i++) {
            if(comp[i] == -1) dfs(i, -1, k);
        }
        group.resize(k);
        for(int i = 0; i < (int) g.size(); i++) {
            group[comp[i]].emplace_back(i);
        }
        tree = Graph< T >(k);
        for(auto &e : bridge) {
            tree.add_edge(comp[e.from], comp[e.to], e.cost);
        }
    }

    explicit TwoEdgeConnectedComponents(const Graph< T > &g) : Graph< T >(g) {}

private:
    void dfs(int idx, int par, int &k) {
        if(par >= 0 && ord[par] >= low[idx]) comp[idx] = comp[par];
        else comp[idx] = k++;
        for(auto &to : g[idx]) {
            if(comp[to] == -1) dfs(to, idx, k);
        }
    }
};

signed main() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    int n, m;
    cin >> n >> m;

    vector<int> w(n);

    for (int i = 0; i < n; ++i) {
        cin >> w[i];
    }

    TwoEdgeConnectedComponents<> g(n);

    for (int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        --u, --v;
        g.add_edge(u, v);
    }

    g.build();

    auto &tree = g.tree;
    auto &comp = g.comp;
    auto &group = g.group;

    int sz = tree.size();

    vector<int> weight(sz);

    for (int i = 0; i < n; ++i) {
        weight[comp[i]] += w[i];
    }

    vector dp(sz, vector(2, 0));
    auto res = makeFixPoint([&](auto rec, int cur, int pre) -> pair<int, int> {
        int maxv = 0, bsum = 0;
        for (auto e : tree[cur]) {
            if (e == pre) continue;
            auto [a, b] = rec(e, cur);
            chmax(maxv, a + weight[e]);
            bsum += b;
        }
        dp[cur][0] = maxv;
        dp[cur][1] = bsum + (group[cur].size() != 1 || bsum != 0 ? weight[cur] : 0);
        return (make_pair(dp[cur][0], dp[cur][1]));
    }) (comp[0], -1);

    cout << max(res.first + (group[comp[0]].size() != 1 ? weight[comp[0]] : 0), res.second) << '\n';

    // for (int i = 0; i < n; ++i) {
    //     cout << i + 1 << " : " << dp[comp[i]][0] << ' ' << dp[comp[i]][1] << '\n';
    // }

    return(0);
}
accuracy: 0.14285714285714285
time_ms: 40
memory_kb: 44788
final_rank: 19

code_snippet: #include <bits/extc++.h>

using namespace std;

#define rep(i,n) for(int i=0;i<(n);++i)
#define reps(i,s,n) for(int i=(s);i<=(n);++i)
#define all(x) begin(x), end(x)
#define Fixed fixed << setprecision(12)
#define updiv(a,b) (((a) + (b) - 1) / (b))
constexpr int32_t INF  = 0x3f3f3f3f;
constexpr int64_t LINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr int mod = 1e9+7;
// constexpr int mod = 998244353;

template <class Func>
class FixPoint : Func {
public:
    explicit constexpr FixPoint(Func&& f) noexcept : Func(forward<Func>(f)) {}

    template <class... Args>
    constexpr decltype(auto) operator()(Args&&... args) const {
        return Func::operator()(*this, std::forward<Args>(args)...);
    }
};

template <class Func>
static inline constexpr decltype(auto) makeFixPoint(Func&& f) noexcept {
    return FixPoint<Func>{forward<Func>(f)};
}

template <class A, class B> inline bool chmax(A &a, const B &b) { return b > a && (a = b, true); }
template <class A, class B> inline bool chmin(A &a, const B &b) { return b < a && (a = b, true); }

template <class T> using max_heap = priority_queue<T>;
template <class T> using min_heap = priority_queue<T,vector<T>,greater<T> >;
template <class A, class B> using umap = unordered_map<A,B>;
template <class A, class B> using uset = unordered_set<A,B>;

template <class T> using Set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;

template <class T> inline void bye(T x) { cout << x << '\n'; exit(0); }

constexpr int dx[] = {1, 0, -1, 0, 1, 1, -1, -1};
constexpr int dy[] = {0, -1, 0, 1, 1, -1, -1, 1};

template< typename T = int >
struct Edge {
    int from, to;
    T cost;
    int idx;

    Edge() = default;

    Edge(int from, int to, T cost = 1, int idx = -1) : from(from), to(to), cost(cost), idx(idx) {}

    operator int() const { return to; }
};

template< typename T = int >
struct Graph {
    vector< vector< Edge< T > > > g;
    int es;

    Graph() = default;

    explicit Graph(int n) : g(n), es(0) {}

    size_t size() const {
        return g.size();
    }

    void add_directed_edge(int from, int to, T cost = 1) {
        g[from].emplace_back(from, to, cost, es++);
    }

    void add_edge(int from, int to, T cost = 1) {
        g[from].emplace_back(from, to, cost, es);
        g[to].emplace_back(to, from, cost, es++);
    }

    void read(int M, int padding = -1, bool weighted = false, bool directed = false) {
        for(int i = 0; i < M; i++) {
            int a, b;
            cin >> a >> b;
            a += padding;
            b += padding;
            T c = T(1);
            if(weighted) cin >> c;
            if(directed) add_directed_edge(a, b, c);
            else add_edge(a, b, c);
        }
    }

    inline vector< Edge< T > > &operator[](const int &k) {
        return g[k];
    }

    inline const vector< Edge< T > > &operator[](const int &k) const {
        return g[k];
    }
};

template< typename T = int >
using Edges = vector< Edge< T > >;

template< typename T = int >
struct LowLink : Graph< T > {
public:
    using Graph< T >::Graph;
    vector< int > ord, low, articulation;
    vector< Edge< T > > bridge;
    using Graph< T >::g;

    virtual void build() {
        used.assign(g.size(), 0);
        ord.assign(g.size(), 0);
        low.assign(g.size(), 0);
        int k = 0;
        for(int i = 0; i < (int) g.size(); i++) {
            if(!used[i]) k = dfs(i, k, -1);
        }
    }

    explicit LowLink(const Graph< T > &g) : Graph< T >(g) {}

private:
    vector< int > used;

    int dfs(int idx, int k, int par) {
        used[idx] = true;
        ord[idx] = k++;
        low[idx] = ord[idx];
        bool is_articulation = false, beet = false;
        int cnt = 0;
        for(auto &to : g[idx]) {
            if(to == par && !exchange(beet, true)) {
                continue;
            }
            if(!used[to]) {
                ++cnt;
                k = dfs(to, k, idx);
                low[idx] = min(low[idx], low[to]);
                is_articulation |= par >= 0 && low[to] >= ord[idx];
                if(ord[idx] < low[to]) bridge.emplace_back(to);
            } else {
                low[idx] = min(low[idx], ord[to]);
            }
        }
        is_articulation |= par == -1 && cnt > 1;
        if(is_articulation) articulation.push_back(idx);
        return k;
    }
};

template< typename T = int >
struct TwoEdgeConnectedComponents : LowLink< T > {
public:
    using LowLink< T >::LowLink;
    using LowLink< T >::g;
    using LowLink< T >::ord;
    using LowLink< T >::low;
    using LowLink< T >::bridge;

    vector< int > comp;
    Graph< T > tree;
    vector< vector< int > > group;

    int operator[](const int &k) const {
        return comp[k];
    }

    void build() override {
        LowLink< T >::build();
        comp.assign(g.size(), -1);
        int k = 0;
        for(int i = 0; i < (int) comp.size(); i++) {
            if(comp[i] == -1) dfs(i, -1, k);
        }
        group.resize(k);
        for(int i = 0; i < (int) g.size(); i++) {
            group[comp[i]].emplace_back(i);
        }
        tree = Graph< T >(k);
        for(auto &e : bridge) {
            tree.add_edge(comp[e.from], comp[e.to], e.cost);
        }
    }

    explicit TwoEdgeConnectedComponents(const Graph< T > &g) : Graph< T >(g) {}

private:
    void dfs(int idx, int par, int &k) {
        if(par >= 0 && ord[par] >= low[idx]) comp[idx] = comp[par];
        else comp[idx] = k++;
        for(auto &to : g[idx]) {
            if(comp[to] == -1) dfs(to, idx, k);
        }
    }
};

signed main() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    int n, m;
    cin >> n >> m;

    vector<int> w(n);

    for (int i = 0; i < n; ++i) {
        cin >> w[i];
    }

    TwoEdgeConnectedComponents<> g(n);

    for (int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        --u, --v;
        g.add_edge(u, v);
    }

    g.build();

    auto &tree = g.tree;
    auto &comp = g.comp;
    auto &group = g.group;

    int sz = tree.size();

    vector<int> weight(sz);

    for (int i = 0; i < n; ++i) {
        weight[comp[i]] += w[i];
    }

    int res = 0;
    auto dfs = makeFixPoint([&](auto rec, int cur, int pre, int sum) -> void {
        chmax(res, sum);
        for (auto e : tree[cur]) {
            if (e == pre) continue;
            rec(e, cur, sum + weight[e]);
        }
    });

    dfs(comp[0], -1, weight[comp[0]] - (group[comp[0]].size() == 1 ? w[0] : 0));

    cout << res << '\n';

    return(0);
}
accuracy: 0.14285714285714285
time_ms: 30
memory_kb: 36216
final_rank: 18

code_snippet: #include <bits/extc++.h>

using namespace std;

#define rep(i,n) for(int i=0;i<(n);++i)
#define reps(i,s,n) for(int i=(s);i<=(n);++i)
#define all(x) begin(x), end(x)
#define Fixed fixed << setprecision(12)
#define updiv(a,b) (((a) + (b) - 1) / (b))
constexpr int32_t INF  = 0x3f3f3f3f;
constexpr int64_t LINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr int mod = 1e9+7;
// constexpr int mod = 998244353;

template <class Func>
class FixPoint : Func {
public:
    explicit constexpr FixPoint(Func&& f) noexcept : Func(forward<Func>(f)) {}

    template <class... Args>
    constexpr decltype(auto) operator()(Args&&... args) const {
        return Func::operator()(*this, std::forward<Args>(args)...);
    }
};

template <class Func>
static inline constexpr decltype(auto) makeFixPoint(Func&& f) noexcept {
    return FixPoint<Func>{forward<Func>(f)};
}

template <class A, class B> inline bool chmax(A &a, const B &b) { return b > a && (a = b, true); }
template <class A, class B> inline bool chmin(A &a, const B &b) { return b < a && (a = b, true); }

template <class T> using max_heap = priority_queue<T>;
template <class T> using min_heap = priority_queue<T,vector<T>,greater<T> >;
template <class A, class B> using umap = unordered_map<A,B>;
template <class A, class B> using uset = unordered_set<A,B>;

template <class T> using Set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;

template <class T> inline void bye(T x) { cout << x << '\n'; exit(0); }

constexpr int dx[] = {1, 0, -1, 0, 1, 1, -1, -1};
constexpr int dy[] = {0, -1, 0, 1, 1, -1, -1, 1};

template< typename T = int >
struct Edge {
    int from, to;
    T cost;
    int idx;

    Edge() = default;

    Edge(int from, int to, T cost = 1, int idx = -1) : from(from), to(to), cost(cost), idx(idx) {}

    operator int() const { return to; }
};

template< typename T = int >
struct Graph {
    vector< vector< Edge< T > > > g;
    int es;

    Graph() = default;

    explicit Graph(int n) : g(n), es(0) {}

    size_t size() const {
        return g.size();
    }

    void add_directed_edge(int from, int to, T cost = 1) {
        g[from].emplace_back(from, to, cost, es++);
    }

    void add_edge(int from, int to, T cost = 1) {
        g[from].emplace_back(from, to, cost, es);
        g[to].emplace_back(to, from, cost, es++);
    }

    void read(int M, int padding = -1, bool weighted = false, bool directed = false) {
        for(int i = 0; i < M; i++) {
            int a, b;
            cin >> a >> b;
            a += padding;
            b += padding;
            T c = T(1);
            if(weighted) cin >> c;
            if(directed) add_directed_edge(a, b, c);
            else add_edge(a, b, c);
        }
    }

    inline vector< Edge< T > > &operator[](const int &k) {
        return g[k];
    }

    inline const vector< Edge< T > > &operator[](const int &k) const {
        return g[k];
    }
};

template< typename T = int >
using Edges = vector< Edge< T > >;

template< typename T = int >
struct LowLink : Graph< T > {
public:
    using Graph< T >::Graph;
    vector< int > ord, low, articulation;
    vector< Edge< T > > bridge;
    using Graph< T >::g;

    virtual void build() {
        used.assign(g.size(), 0);
        ord.assign(g.size(), 0);
        low.assign(g.size(), 0);
        int k = 0;
        for(int i = 0; i < (int) g.size(); i++) {
            if(!used[i]) k = dfs(i, k, -1);
        }
    }

    explicit LowLink(const Graph< T > &g) : Graph< T >(g) {}

private:
    vector< int > used;

    int dfs(int idx, int k, int par) {
        used[idx] = true;
        ord[idx] = k++;
        low[idx] = ord[idx];
        bool is_articulation = false, beet = false;
        int cnt = 0;
        for(auto &to : g[idx]) {
            if(to == par && !exchange(beet, true)) {
                continue;
            }
            if(!used[to]) {
                ++cnt;
                k = dfs(to, k, idx);
                low[idx] = min(low[idx], low[to]);
                is_articulation |= par >= 0 && low[to] >= ord[idx];
                if(ord[idx] < low[to]) bridge.emplace_back(to);
            } else {
                low[idx] = min(low[idx], ord[to]);
            }
        }
        is_articulation |= par == -1 && cnt > 1;
        if(is_articulation) articulation.push_back(idx);
        return k;
    }
};

template< typename T = int >
struct TwoEdgeConnectedComponents : LowLink< T > {
public:
    using LowLink< T >::LowLink;
    using LowLink< T >::g;
    using LowLink< T >::ord;
    using LowLink< T >::low;
    using LowLink< T >::bridge;

    vector< int > comp;
    Graph< T > tree;
    vector< vector< int > > group;

    int operator[](const int &k) const {
        return comp[k];
    }

    void build() override {
        LowLink< T >::build();
        comp.assign(g.size(), -1);
        int k = 0;
        for(int i = 0; i < (int) comp.size(); i++) {
            if(comp[i] == -1) dfs(i, -1, k);
        }
        group.resize(k);
        for(int i = 0; i < (int) g.size(); i++) {
            group[comp[i]].emplace_back(i);
        }
        tree = Graph< T >(k);
        for(auto &e : bridge) {
            tree.add_edge(comp[e.from], comp[e.to], e.cost);
        }
    }

    explicit TwoEdgeConnectedComponents(const Graph< T > &g) : Graph< T >(g) {}

private:
    void dfs(int idx, int par, int &k) {
        if(par >= 0 && ord[par] >= low[idx]) comp[idx] = comp[par];
        else comp[idx] = k++;
        for(auto &to : g[idx]) {
            if(comp[to] == -1) dfs(to, idx, k);
        }
    }
};

signed main() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    int n, m;
    cin >> n >> m;

    vector<int> w(n);

    for (int i = 0; i < n; ++i) {
        cin >> w[i];
    }

    TwoEdgeConnectedComponents<> g(n);

    for (int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        --u, --v;
        g.add_edge(u, v);
    }

    g.build();

    auto &tree = g.tree;
    auto &comp = g.comp;
    auto &group = g.group;

    int sz = tree.size();

    vector<int> weight(sz);

    for (int i = 0; i < n; ++i) {
        weight[comp[i]] += w[i];
    }

    int res = 0;
    auto dfs = makeFixPoint([&](auto rec, int cur, int pre, int sum) -> void {
        chmax(res, sum);
        for (auto e : tree[cur]) {
            if (e == pre) continue;
            rec(e, cur, sum + weight[e]);
        }
    });

    dfs(comp[0], -1, weight[comp[0]]);

    cout << res << '\n';

    return(0);
}
accuracy: 0.5238095238095238
time_ms: 40
memory_kb: 36212
final_rank: 12

code_snippet: #include <bits/extc++.h>

using namespace std;

#define rep(i,n) for(int i=0;i<(n);++i)
#define reps(i,s,n) for(int i=(s);i<=(n);++i)
#define all(x) begin(x), end(x)
#define Fixed fixed << setprecision(12)
#define updiv(a,b) (((a) + (b) - 1) / (b))
constexpr int32_t INF  = 0x3f3f3f3f;
constexpr int64_t LINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr int mod = 1e9+7;
// constexpr int mod = 998244353;

template <class Func>
class FixPoint : Func {
public:
    explicit constexpr FixPoint(Func&& f) noexcept : Func(forward<Func>(f)) {}

    template <class... Args>
    constexpr decltype(auto) operator()(Args&&... args) const {
        return Func::operator()(*this, std::forward<Args>(args)...);
    }
};

template <class Func>
static inline constexpr decltype(auto) makeFixPoint(Func&& f) noexcept {
    return FixPoint<Func>{forward<Func>(f)};
}

template <class A, class B> inline bool chmax(A &a, const B &b) { return b > a && (a = b, true); }
template <class A, class B> inline bool chmin(A &a, const B &b) { return b < a && (a = b, true); }

template <class T> using max_heap = priority_queue<T>;
template <class T> using min_heap = priority_queue<T,vector<T>,greater<T> >;
template <class A, class B> using umap = unordered_map<A,B>;
template <class A, class B> using uset = unordered_set<A,B>;

template <class T> using Set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;

template <class T> inline void bye(T x) { cout << x << '\n'; exit(0); }

constexpr int dx[] = {1, 0, -1, 0, 1, 1, -1, -1};
constexpr int dy[] = {0, -1, 0, 1, 1, -1, -1, 1};

template< typename T = int >
struct Edge {
    int from, to;
    T cost;
    int idx;

    Edge() = default;

    Edge(int from, int to, T cost = 1, int idx = -1) : from(from), to(to), cost(cost), idx(idx) {}

    operator int() const { return to; }
};

template< typename T = int >
struct Graph {
    vector< vector< Edge< T > > > g;
    int es;

    Graph() = default;

    explicit Graph(int n) : g(n), es(0) {}

    size_t size() const {
        return g.size();
    }

    void add_directed_edge(int from, int to, T cost = 1) {
        g[from].emplace_back(from, to, cost, es++);
    }

    void add_edge(int from, int to, T cost = 1) {
        g[from].emplace_back(from, to, cost, es);
        g[to].emplace_back(to, from, cost, es++);
    }

    void read(int M, int padding = -1, bool weighted = false, bool directed = false) {
        for(int i = 0; i < M; i++) {
            int a, b;
            cin >> a >> b;
            a += padding;
            b += padding;
            T c = T(1);
            if(weighted) cin >> c;
            if(directed) add_directed_edge(a, b, c);
            else add_edge(a, b, c);
        }
    }

    inline vector< Edge< T > > &operator[](const int &k) {
        return g[k];
    }

    inline const vector< Edge< T > > &operator[](const int &k) const {
        return g[k];
    }
};

template< typename T = int >
using Edges = vector< Edge< T > >;

template< typename T = int >
struct LowLink : Graph< T > {
public:
    using Graph< T >::Graph;
    vector< int > ord, low, articulation;
    vector< Edge< T > > bridge;
    using Graph< T >::g;

    virtual void build() {
        used.assign(g.size(), 0);
        ord.assign(g.size(), 0);
        low.assign(g.size(), 0);
        int k = 0;
        for(int i = 0; i < (int) g.size(); i++) {
            if(!used[i]) k = dfs(i, k, -1);
        }
    }

    explicit LowLink(const Graph< T > &g) : Graph< T >(g) {}

private:
    vector< int > used;

    int dfs(int idx, int k, int par) {
        used[idx] = true;
        ord[idx] = k++;
        low[idx] = ord[idx];
        bool is_articulation = false, beet = false;
        int cnt = 0;
        for(auto &to : g[idx]) {
            if(to == par && !exchange(beet, true)) {
                continue;
            }
            if(!used[to]) {
                ++cnt;
                k = dfs(to, k, idx);
                low[idx] = min(low[idx], low[to]);
                is_articulation |= par >= 0 && low[to] >= ord[idx];
                if(ord[idx] < low[to]) bridge.emplace_back(to);
            } else {
                low[idx] = min(low[idx], ord[to]);
            }
        }
        is_articulation |= par == -1 && cnt > 1;
        if(is_articulation) articulation.push_back(idx);
        return k;
    }
};

template< typename T = int >
struct TwoEdgeConnectedComponents : LowLink< T > {
public:
    using LowLink< T >::LowLink;
    using LowLink< T >::g;
    using LowLink< T >::ord;
    using LowLink< T >::low;
    using LowLink< T >::bridge;

    vector< int > comp;
    Graph< T > tree;
    vector< vector< int > > group;

    int operator[](const int &k) const {
        return comp[k];
    }

    void build() override {
        LowLink< T >::build();
        comp.assign(g.size(), -1);
        int k = 0;
        for(int i = 0; i < (int) comp.size(); i++) {
            if(comp[i] == -1) dfs(i, -1, k);
        }
        group.resize(k);
        for(int i = 0; i < (int) g.size(); i++) {
            group[comp[i]].emplace_back(i);
        }
        tree = Graph< T >(k);
        for(auto &e : bridge) {
            tree.add_edge(comp[e.from], comp[e.to], e.cost);
        }
    }

    explicit TwoEdgeConnectedComponents(const Graph< T > &g) : Graph< T >(g) {}

private:
    void dfs(int idx, int par, int &k) {
        if(par >= 0 && ord[par] >= low[idx]) comp[idx] = comp[par];
        else comp[idx] = k++;
        for(auto &to : g[idx]) {
            if(comp[to] == -1) dfs(to, idx, k);
        }
    }
};

signed main() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    int n, m;
    cin >> n >> m;

    vector<int> w(n);

    for (int i = 0; i < n; ++i) {
        cin >> w[i];
    }

    TwoEdgeConnectedComponents<> g(n);

    for (int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        --u, --v;
        g.add_edge(u, v);
    }

    g.build();

    auto &tree = g.tree;
    auto &comp = g.comp;
    auto &group = g.group;

    int sz = tree.size();

    vector<int> weight(sz);

    for (int i = 0; i < n; ++i) {
        weight[comp[i]] += w[i];
    }

    int maxv = 0, maxn = 0;
    auto dfs = makeFixPoint([&](auto rec, int cur, int pre, int sum) -> void {
        if (chmax(maxv, sum)) maxn = cur;
        for (auto e : tree[cur]) {
            if (e == pre) continue;
            rec(e, cur, sum + weight[e]);
        }
    });

    dfs(0, -1, weight[0]);
    dfs(maxn, 0, weight[maxn]);

    cout << maxv << '\n';

    return(0);
}
accuracy: 0.19047619047619047
time_ms: 40
memory_kb: 36180
final_rank: 17

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,...) for(int i = (a)*(strlen(#__VA_ARGS__)!=0);i<(int)(strlen(#__VA_ARGS__)?__VA_ARGS__:(a));++i)
#define per(i,a,...) for(int i = (strlen(#__VA_ARGS__)?__VA_ARGS__:(a))-1;i>=(int)(strlen(#__VA_ARGS__)?(a):0);--i)
#define foreach(i, n) for(auto &i:(n))
#define all(x) (x).begin(), (x).end()
#define bit(x) (1ll << (x))
#define lambda(RES_TYPE, ...) (function<RES_TYPE(__VA_ARGS__)>)[&](__VA_ARGS__) -> RES_TYPE
#define method(FUNC_NAME, RES_TYPE, ...) function<RES_TYPE(__VA_ARGS__)> FUNC_NAME = lambda(RES_TYPE, __VA_ARGS__)
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
//const ll MOD = (ll)1e9+7;
const ll MOD = 998244353;
const int INF = (ll)1e9+7;
const ll INFLL = (ll)1e18;
template<class t>
using vvector = vector<vector<t>>;
template<class t>
using vvvector = vector<vector<vector<t>>>;
template<class t>
using priority_queuer = priority_queue<t, vector<t>, greater<t>>;
template<class t, class u> bool chmax(t &a, u b){if(a<b){a=b;return true;}return false;}
template<class t, class u> bool chmin(t &a, u b){if(a>b){a=b;return true;}return false;}
#ifdef DEBUG
#define debug(x) cout<<"LINE "<<__LINE__<<": "<<#x<<" = "<<x<<endl;
#else
#define debug(x) (void)0
#endif

namespace templates{
    ll modpow(ll x, ll b,ll mod=MOD){
        ll res = 1;
        while(b){
            if(b&1)res = res * x % mod;
            x = x * x % mod;
            b>>=1;
        }
        return res;
    }

    ll modinv(ll x){
        return modpow(x, MOD-2);
    }

    bool was_output = false;

    void print();
    template <class t> void print(const vector<t> &);
    template <class t, class u> void print(const pair<t, u> &);
    template <class t> void print(const t&);
    template <class Head, class... Tail> void print(const Head&, const Tail&...);

    template <class t> void println(const vector<vector<t>>&);
    template <class t> void println(const vector<t>&);
    template <class t> void println(const t&);
    template <class Head, class... Tail> void println(const Head&, const Tail&...);
    void println();
    void newline();

    void print(){
        return;
    }

    template <class t>
    void print(const vector<t>&x){
        for(const t&i:x)print(i);
    }
    template <class t, class u>
    void print(const pair<t,u>&p){
        print(p.first);
        print(p.second);
    }
    template <class t>
    void print(const t&x){
        if(was_output)cout<<" ";
        cout<<x;
        was_output = true;
    }
    template <class Head, class... Tail>
    void print(const Head&head,const Tail&...tail){
        print(head);
        print(tail...);
    }

    template<class t>
    void println(const vector<vector<t>>&x){
        for(vector<t> i:x)println(i);
    }
    template<class t>
    void println(const vector<t>&x){
        for(const t&i:x)print(i);
        println();
    }
    template <class t>
    void println(const t&x){
        print(x);
        println();
    }
    void println(){
        if(was_output){
            cout << endl;
            was_output = false;
        }
    }
    template <class Head, class... Tail>
    void println(const Head&head,const Tail&...tail){
        print(head);
        println(tail...);
    }

    void newline(){
        was_output = true;
        println();
    }

    template<class t>
    istream& operator>>(istream&is, vector<t>&x){
        for(auto &i:x)is >> i;
        return is;
    }

    template<class t, class u>
    istream& operator>>(istream&is, pair<t, u>&x){
        is >> x.first >> x.second;
        return is;
    }

    template<class t>
    ostream& operator<<(ostream&os, vector<t> &v){
        os << "{";
        for(t &i:v){
            os << i << ", ";
        }
        os << "}";
        return os;
    }

    template<class t = long long>
    t in(){
        t res; cin >> res; return res;
    }

    template<class t>
    vector<t> sorted(vector<t> line,function<bool(t,t)> comp=[](t a,t b){return a<b;}){
        sort(line.begin(),line.end(),comp);
        return line;
    }

    template<class t>
    vector<t> reversed(vector<t> line){
        reverse(line.begin(),line.end());
        return line;
    }
    string reversed(string str){
        reverse(str.begin(),str.end());
        return str;
    }

    long long gcd(long long a,long long b){
        while(b){
            a %= b;
            swap(a,b);
        }
        return a;
    }

    long long lcm(long long a,long long b){
        return a / gcd(a,b) * b;
    }

    class output_initializer{
    public:
        output_initializer(){
            ios::sync_with_stdio(false);
            cin.tie(nullptr);
            cout << setprecision(20);
        }
    };output_initializer OUTPUT_INITIALIZER_INSTANCE = output_initializer();
}

using namespace templates;

template< typename G >
struct LowLink {
  const G &g;
  vector< int > used, ord, low;
  vector< int > articulation;
  vector< pair< int, int > > bridge;
 
  LowLink(const G &g) : g(g) {}
 
  int dfs(int idx, int k, int par) {
    used[idx] = true;
    ord[idx] = k++;
    low[idx] = ord[idx];
    bool is_articulation = false;
    int cnt = 0;
    for(auto &to : g[idx]) {
      if(!used[to]) {
        ++cnt;
        k = dfs(to, k, idx);
        low[idx] = min(low[idx], low[to]);
        is_articulation |= ~par && low[to] >= ord[idx];
        if(ord[idx] < low[to]) bridge.emplace_back(minmax(idx, (int) to));
      } else if(to != par) {
        low[idx] = min(low[idx], ord[to]);
      }
    }
    is_articulation |= par == -1 && cnt > 1;
    if(is_articulation) articulation.push_back(idx);
    return k;
  }
 
  virtual void build() {
    used.assign(g.size(), 0);
    ord.assign(g.size(), 0);
    low.assign(g.size(), 0);
    int k = 0;
    for(int i = 0; i < g.size(); i++) {
      if(!used[i]) k = dfs(i, k, -1);
    }
  }
};

using UnWeightedGraph = vvector<int>;

template< typename G >
struct TwoEdgeConnectedComponents : LowLink< G > {
  using LL = LowLink< G >;
  vector< int > comp;
 
  TwoEdgeConnectedComponents(const G &g) : LL(g) {}
 
  int operator[](const int &k) {
    return comp[k];
  }
 
  void dfs(int idx, int par, int &k) {
    if(~par && this->ord[par] >= this->low[idx]) comp[idx] = comp[par];
    else comp[idx] = k++;
    for(auto &to : this->g[idx]) {
      if(comp[to] == -1) dfs(to, idx, k);
    }
  }
 
  void build(UnWeightedGraph &t) {
    LL::build();
    comp.assign(this->g.size(), -1);
    int k = 0;
    for(int i = 0; i < comp.size(); i++) {
      if(comp[i] == -1) dfs(i, -1, k);
    }
    t.resize(k);
    for(auto &e : this->bridge) {
      int x = comp[e.first], y = comp[e.second];
      t[x].push_back(y);
      t[y].push_back(x);
    }
  }
};

ll func(){
    int n = in();
    int m = in();
    vvector<int> edges(n);
    vector<ll> line(n);
    foreach(i,line)i=in();
    rep(_,m){
        int a = in()-1;
        int b = in()-1;
        edges[a].emplace_back(b);
        edges[b].emplace_back(a);
    }
    TwoEdgeConnectedComponents<vvector<int>> G(edges);
    vvector<int> ps;
    G.build(ps);
    vector<int> points(n,0);
    vector<int> has(n,0);
    rep(i,n){
        points[G.comp[i]] += line[i];
        ++has[G.comp[i]];
    }
    vvector<int> dp(2,vector<int>(n,-INF));
    vector<int> child_dp(n,-1);
    method(has_ok,bool,int p,int last){
        if(has[p] >= 2)return true;
        int &it = child_dp[p];
        if(it >= 0)return it;
        it = false;
        foreach(e,ps[p]){
            if(e==last)continue;
            it = it or has_ok(e,p);
        }
        return it;
    };
    method(rec,int,int p,bool back,int last){
        int &it = dp[back][p];
        if(it != -INF)return it;
        if(back){
            it = points[p];
            foreach(e,ps[p]){
                if(e==last)continue;
                if(not has_ok(e,p))continue;
                it += rec(e,true,p);
            }
        }else{
            int sum = points[p];
            it = points[p];
            foreach(e,ps[p]){
                if(e==last)continue;
                if(not has_ok(e,p))continue;
                sum += rec(e,true,p);
            }
            foreach(e,ps[p]){
                if(e==last)continue;
                if(has_ok(e,p)){
                    chmax(it,sum+rec(e,false,p)-rec(e,true,p));
                }else{
                    chmax(it,sum+rec(e,false,p));
                }
            }
        }
        return it;
    };
    return rec(G.comp[0],false,-1);
}

int main(){
    println(func());
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 34888
final_rank: 7