#include<bits/stdc++.h>
using namespace std;
#define lop(i,n) for(i=0;i<n;i++)
#define lop1(i,n) for(ll i=1;i<=n;i++)
#define lopr(i,n) for(i=n-1;i>=0;i--)
#define ll long long int
#define pb push_back
#define all(v) v.begin(),v.end()
#define IOS  ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define endl "\n"
#define F first
#define S second
#define mem(arr,val) memset(arr,val,sizeof(arr))
#define pii pair<int,int>
#define pll pair<ll,ll>
#define LCM(a,b) (a*b)/__gcd(a,b)
#define mii map<int,int>
#define mll map<ll,ll>
#define ub upper_bound
#define lb lower_bound
#define sz(x) (ll)x.size()
#define ld long double
#define pcnt(x) __builtin_popcountll(x)
const long long I1 = 1e9 + 7;
const long long I2 = 1e18;
const long long MAXM = 1e6 + 5;

template<typename T, typename T1>T maxn(T &a, T1 b) {if (b > a)a = b; return a;}
template<typename T, typename T1>T minn(T &a, T1 b) {if (b < a)a = b; return a;}

bool isPrime(ll n)
{
  // Corner case
  if (n <= 1)
    return false;

  // Check from 2 to n-1
  for (ll i = 2; i < n; i++)
    if (n % i == 0)
      return false;

  return true;
}
bool isPalindrome(string s) {
  ll n = s.length();
  ll i;
  lop(i, n / 2) {
    if (s[i] != s[n - i - 1])
      return false;
  }
  return true;
}
unsigned long long power(unsigned long long x,
                         ll y, ll p)
{
  unsigned long long res = 1; // Initialize result

  x = x % p; // Update x if it is more than or
  // equal to p

  while (y > 0)
  {

    // If y is odd, multiply x with result
    if (y & 1)
      res = (res * x) % p;

    // y must be even now
    y = y >> 1; // y = y/2
    x = (x * x) % p;
  }
  return res;
}

// Returns n^(-1) mod p
unsigned long long modInverse(unsigned long long n,
                              ll p)
{
  return power(n, p - 2, p);
}

// Returns nCr % p using Fermat's little
// theorem.
unsigned long long nCrModPFermat(unsigned long long n,
                                 long long r, ll p)
{
  // If n<r, then nCr should return 0
  if (n < r)
    return 0;
  // Base case
  if (r == 0)
    return 1;

  // Fill factorial array so that we
  // can find all factorial of r, n
  // and n-r
  unsigned long long fac[n + 1];
  fac[0] = 1;
  for (int i = 1; i <= n; i++)
    fac[i] = (fac[i - 1] * i) % p;

  return (fac[n] * modInverse(fac[r], p) % p
          * modInverse(fac[n - r], p) % p)
         % p;
}
ll nCrModp(ll n, ll r, ll p)
{
  // Optimization for the cases when r is large
  if (r > n - r)
    r = n - r;

  // The array C is going to store last row of
  // pascal triangle at the end. And last entry
  // of last row is nCr
  ll C[r + 1];
  memset(C, 0, sizeof(C));

  C[0] = 1; // Top row of Pascal Triangle

  // One by constructs remaining rows of Pascal
  // Triangle from top to bottom
  for (ll i = 1; i <= n; i++) {

    // Fill entries of current row using previous
    // row values
    for (ll j = min(i, r); j > 0; j--)

      // nCj = (n-1)Cj + (n-1)C(j-1);
      C[j] = (C[j] + C[j - 1]) % p;
  }
  return C[r];
}
ll dearrangement(ll n) {
  if (n == 1)
    return 0;
  if (n == 2)
    return 1;
  ll mod = pow(10, 12) + 7;
  ll x = (dearrangement(n - 1) + dearrangement(n - 2)) % mod ;
  x = (x * (n - 1)) % mod;
  return x;
}
ll factors[MAXM];
void calcFactors() {
  factors[0] = 0;
  factors[1] = 0;
  ll val[MAXM];
  ll i;
  lop(i, MAXM)
  val[i] = i;
  ll j;
  for (i = 2; i < MAXM; i++) {
    if (val[i] == i) {
      for (j = i * i; j < MAXM; j += i)
        val[j] = i;
    }
  }
  for (i = 2; i < MAXM; i++) {
    factors[i] = 1;
    if (val[i] != i) {
      // if (i <= 10)
      //   cout << val[i] << " " << i / val[i] << endl;
      factors[i] += factors[val[i]];
      factors[i] += factors[i / val[i]];
      if (val[i] == i / val[i])
        factors[i]--;
    }
  }
}
bool cmp(pll x, pll y) {
  if (x.F != y.F)
    return x.F > y.F;
  return x.S < y.S;
}
struct node {
  int val;
  vector<node *> ch;
  node *par;
};
void dfs(node* root, string s) {
  string str;
  for (node* tmp : root->ch) {
    // cout << root->val << " " << tmp->val << endl;
    str = s;
    if (root->val != -1)
      str += ".";
    str += to_string(tmp->val);
    cout << str << endl;
    dfs(tmp, str);
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  ll t;
  cin >> t;
  // t = 1;
  while (t--) {
    ll n;
    cin >> n;
    ll a[n];
    ll i = 0;
    lop(i, n)
    cin >> a[i];
    node* root = new node;
    root->val = -1;
    root-> par = NULL;
    node* cur = root;
    i = 0;
    while (i < n) {
      node* tmp = new node;
      tmp->val = a[i];
      while (!(a[i] == 1 || (a[i] == cur->val + 1)))
        cur = cur->par;
      if (a[i] == 1) {
        if (cur->ch.size() == 0) {
          tmp->par = cur;
          cur->ch.push_back(tmp);
          cur = tmp;
        }
        i++;
      }
      else if (a[i] == cur->val + 1) {
        cur = cur->par;
        tmp->par = cur;
        cur->ch.push_back(tmp);
        cur = tmp;
        i++;
      }
    }
    dfs(root, "");

  }
  return 0;
}