#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const long long N = 3e5 + 2;
long long n;
int grp = 0;
vector<int> g[N], newg[N], rg[N], todo;
int comp[N], sz[N];
bool vis[N];
set<pair<long long, long long> > edges;
void init() {
  grp = 0;
  for (long long i = 0; i <= n; i++) {
    g[i].clear();
    newg[i].clear();
    rg[i].clear();
    sz[i] = 0;
  }
  todo.clear();
  edges.clear();
  memset(vis, false, sizeof(vis));
}
void dfs(int u) {
  vis[u] = 1;
  for (auto &it : g[u]) {
    if (!vis[it]) dfs(it);
  }
  todo.push_back(u);
}
void dfs2(int u, int val) {
  comp[u] = val;
  sz[val]++;
  for (auto &it : rg[u]) {
    if (comp[it] == -1) dfs2(it, val);
  }
}
void sccAddEdge(int from, int to) {
  if (edges.find({from, to}) != edges.end()) return;
  edges.insert({from, to});
  g[from].push_back(to);
  rg[to].push_back(from);
}
void scc() {
  for (int i = 1; i <= n; i++) comp[i] = -1;
  for (int i = 1; i <= n; i++) {
    if (!vis[i]) dfs(i);
  }
  reverse(todo.begin(), todo.end());
  for (auto &it : todo) {
    if (comp[it] == -1) dfs2(it, ++grp);
  }
}
void solve() {
  cin >> n;
  init();
  string s;
  cin >> s;
  for (long long i = 0; i < n; i++) {
    if (s[i] == '<') {
      sccAddEdge((i + 1) % n + 1, i + 1);
    } else if (s[i] == '>') {
      sccAddEdge(i + 1, (i + 1) % n + 1);
    } else {
      sccAddEdge(i + 1, (i + 1) % n + 1);
      sccAddEdge((i + 1) % n + 1, i + 1);
    }
  }
  scc();
  long long ans = 0;
  for (long long i = 1; i <= n; i++) {
    if (sz[comp[i]] > 1) {
      ++ans;
    }
  }
  cout << ans << '\n';
  return;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(NULL);
  long long t;
  cin >> t;
  while (t--) {
    solve();
  }
  return 0;
}
