description: There is a grid, consisting of n rows and m columns. Each cell of the grid is either free or blocked. One of the free cells contains a lab. All the cells beyond the borders of the grid are also blocked.
  
  A crazy robot has escaped from this lab. It is currently in some free cell of the grid. You can send one of the following commands to the robot: "move right", "move down", "move left" or "move up". Each command means moving to a neighbouring cell in the corresponding direction.
  
  However, as the robot is crazy, it will do anything except following the command. Upon receiving a command, it will choose a direction such that it differs from the one in command and the cell in that direction is not blocked. If there is such a direction, then it will move to a neighbouring cell in that direction. Otherwise, it will do nothing.
  
  We want to get the robot to the lab to get it fixed. For each free cell, determine if the robot can be forced to reach the lab starting in this cell. That is, after each step of the robot a command can be sent to a robot such that no matter what different directions the robot chooses, it will end up in a lab.
  
  Input
  
  The first line contains a single integer t (1 ≤ t ≤ 1000) — the number of testcases.
  
  The first line of each testcase contains two integers n and m (1 ≤ n, m ≤ 10^6; n ⋅ m ≤ 10^6) — the number of rows and the number of columns in the grid.
  
  The i-th of the next n lines provides a description of the i-th row of the grid. It consists of m elements of one of three types: 
  
    * '.' — the cell is free; 
    * '#' — the cell is blocked; 
    * 'L' — the cell contains a lab. 
  
  
  
  The grid contains exactly one lab. The sum of n ⋅ m over all testcases doesn't exceed 10^6.
  
  Output
  
  For each testcase find the free cells that the robot can be forced to reach the lab from. Given the grid, replace the free cells (marked with a dot) with a plus sign ('+') for the cells that the robot can be forced to reach the lab from. Print the resulting grid.
  
  Example
  
  Input
  
  
  4
  3 3
  ...
  .L.
  ...
  4 5
  #....
  ..##L
  ...#.
  .....
  1 1
  L
  1 9
  ....L..#.
  
  
  Output
  
  
  ...
  .L.
  ...
  #++++
  ..##L
  ...#+
  ...++
  L
  ++++L++#.
  
  Note
  
  In the first testcase there is no free cell that the robot can be forced to reach the lab from. Consider a corner cell. Given any direction, it will move to a neighbouring border grid that's not a corner. Now consider a non-corner free cell. No matter what direction you send to the robot, it can choose a different direction such that it ends up in a corner.
  
  In the last testcase, you can keep sending the command that is opposite to the direction to the lab and the robot will have no choice other than move towards the lab.
solution: import java.io.*;
  import java.util.*;
  import java.math.*;
  
  /**
   __                  __
   ( _)                ( _)
   / / \\              / /\_\_
   / /   \\            / / | \ \
   / /     \\          / /  |\ \ \
   /  /   ,  \ ,       / /   /|  \ \
   /  /    |\_ /|      / /   / \   \_\
   /  /  |\/ _ '_| \   / /   /   \    \\
   |  /   |/  0 \0\    / |    |    \    \\
   |    |\|      \_\_ /  /    |     \    \\
   |  | |/    \.\ o\o)  /      \     |    \\
   \    |     /\\`v-v  /        |    |     \\
   | \/    /_| \\_|  /         |    | \    \\
   | |    /__/_ `-` /   _____  |    |  \    \\
   \|    [__]  \_/  |_________  \   |   \    ()
   /    [___] (    \         \  |\ |   |   //
   |    [___]                  |\| \|   /  |/
   /|    [____]                  \  |/\ / / ||
   (  \   [____ /     ) _\      \  \    \| | ||
   \  \  [_____|    / /     __/    \   / / //
   |   \ [_____/   / /        \    |   \/ //
   |   /  '----|   /=\____   _/    |   / //
   __ /  /        |  /   ___/  _/\    \  | ||
   (/-(/-\)       /   \  (/\/\)/  |    /  | /
   (/\/\)           /   /   //
   _________/   /    /
   \____________/    (
  
  
   @author NTUDragons-Reborn
   */
  
  public class Solution{
      public static void main(String[] args) {
          InputStream inputStream = System.in;
          OutputStream outputStream = System.out;
          InputReader in = new InputReader(inputStream);
          PrintWriter out = new PrintWriter(outputStream);
          Task solver = new Task();
          solver.solve(in, out);
          out.close();
      }
      // main solver
      static class Task{
  
          double eps= 0.00000001;
          static final int MAXN = 200015;
          static final int MOD= 998244353;
  
          // stores smallest prime factor for every number
          static int spf[] = new int[MAXN];
  
          static boolean[] prime;
  
          Map<Integer,Set<Integer>> dp= new HashMap<>();
  
          // Calculating SPF (Smallest Prime Factor) for every
          // number till MAXN.
          // Time Complexity : O(nloglogn)
          public void sieve()
          {
              spf[1] = 1;
              for (int i=2; i<MAXN; i++)
  
                  // marking smallest prime factor for every
                  // number to be itself.
                  spf[i] = i;
  
              // separately marking spf for every even
              // number as 2
              for (int i=4; i<MAXN; i+=2)
                  spf[i] = 2;
  
              for (int i=3; i*i<MAXN; i++)
              {
                  // checking if i is prime
                  if (spf[i] == i)
                  {
                      // marking SPF for all numbers divisible by i
                      for (int j=i*i; j<MAXN; j+=i)
  
                          // marking spf[j] if it is not
                          // previously marked
                          if (spf[j]==j)
                              spf[j] = i;
                  }
              }
          }
  
          void sieveOfEratosthenes(int n)
          {
              // Create a boolean array
              // "prime[0..n]" and
              // initialize all entries
              // it as true. A value in
              // prime[i] will finally be
              // false if i is Not a
              // prime, else true.
              prime= new boolean[n + 1];
              for (int i = 0; i <= n; i++)
                  prime[i] = true;
      
              for (int p = 2; p * p <= n; p++)
              {
                  // If prime[p] is not changed, then it is a
                  // prime
                  if (prime[p] == true)
                  {
                      // Update all multiples of p
                      for (int i = p * p; i <= n; i += p)
                          prime[i] = false;
                  }
              }
          }
  
          // A O(log n) function returning primefactorization
          // by dividing by smallest prime factor at every step
          public Set<Integer> getFactorization(int x)
          {
              if(dp.containsKey(x)) return dp.get(x);
              Set<Integer> ret = new HashSet<>();
              while (x != 1)
              {
                  if(spf[x]!=2) ret.add(spf[x]);
                  x = x / spf[x];
              }
              dp.put(x,ret);
              return ret;
          }
          // function to find first index >= x
          public int lowerIndex(List<Integer> arr, int n, int x)
          {
              int l = 0, h = n - 1;
              while (l <= h)
              {
                  int mid = (l + h) / 2;
                  if (arr.get(mid) >= x)
                      h = mid - 1;
                  else
                      l = mid + 1;
              }
              return l;
          }
          public int lowerIndex(int[] arr, int n, int x)
          {
              int l = 0, h = n - 1;
              while (l <= h)
              {
                  int mid = (l + h) / 2;
                  if (arr[mid] >= x)
                      h = mid - 1;
                  else
                      l = mid + 1;
              }
              return l;
          }
  
          // function to find last index <= y
          public int upperIndex(List<Integer> arr, int n, int y)
          {
              int l = 0, h = n - 1;
              while (l <= h)
              {
                  int mid = (l + h) / 2;
                  if (arr.get(mid) <= y)
                      l = mid + 1;
                  else
                      h = mid - 1;
              }
              return h;
          }
          public int upperIndex(int[] arr, int n, int y)
          {
              int l = 0, h = n - 1;
              while (l <= h)
              {
                  int mid = (l + h) / 2;
                  if (arr[mid] <= y)
                      l = mid + 1;
                  else
                      h = mid - 1;
              }
              return h;
          }
  
          // function to count elements within given range
          public int countInRange(List<Integer> arr, int n, int x, int y)
          {
              // initialize result
              int count = 0;
              count = upperIndex(arr, n, y) -
                      lowerIndex(arr, n, x) + 1;
              return count;
          }
  
          public int add(int a, int b){
              a+=b;
              while(a>=MOD) a-=MOD;
              while(a<0) a+=MOD;
              return a;
          }
  
          public int mul(int a, int b){
              long res= (long)a*(long)b;
              return (int)(res%MOD);
          }
  
          public int power(int a, int b) {
              int ans=1;
              while(b>0){
                  if((b&1)!=0) ans= mul(ans,a);
                  b>>=1;
                  a= mul(a,a);
              }
              return ans;
          }
  
          int[] fact= new int[MAXN];
          int[] inv= new int[MAXN];
  
          public int Ckn(int n, int k){
              if(k<0 || n<0) return 0;
              return mul(mul(fact[n],inv[k]),inv[n-k]);
          }
  
          public int inverse(int a){
              return power(a,MOD-2);
          }
  
          public void preprocess() {
              fact[0]=1;
              for(int i=1;i<MAXN;i++) fact[i]= mul(fact[i-1],i);
              inv[MAXN-1]= inverse(fact[MAXN-1]);
              for(int i=MAXN-2;i>=0;i--){
                  inv[i]= mul(inv[i+1],i+1);
              }
          }
  
          /**
           * return VALUE of lower bound for unsorted array
           */
          public int lowerBoundNormalArray(int[] arr, int x){
              TreeSet<Integer> set= new TreeSet<>();
              for(int num: arr) set.add(num);
              return set.lower(x);
          }
          /**
           * return VALUE of upper bound for unsorted array
           */
          public int upperBoundNormalArray(int[] arr, int x){
              TreeSet<Integer> set= new TreeSet<>();
              for(int num: arr) set.add(num);
              return set.higher(x);
          }
  
          public void debugArr(int[] arr){
              for(int i: arr) out.print(i+" ");
              out.println();
          }
  
          public int rand(){
              int min=0, max= MAXN;
              int random_int = (int)Math.floor(Math.random()*(max-min+1)+min);
              return random_int;
          }
          
          InputReader in; PrintWriter out;
          CustomFileReader cin;
          int[] xor= new int[3*100000+5];
          int[] pow2= new int[1000000+1];
          public void solve(InputReader in, PrintWriter out) {
              this.in=in; this.out=out;
              // sieve();
              // pow2[0]=1;
              // for(int i=1;i<pow2.length;i++){
              //     pow2[i]= mul(pow2[i-1],2);
              // }
              int t= in.nextInt();
              // preprocess();
              // int t=in.nextInt();
              // int t= cin.nextIntArrLine()[0];
              for(int i=1;i<=t;i++) solveA(i);
          }
      
          final double pi= Math.acos(-1);
          static Point base;
  
          int[] par;
          int[] size;
  
          PriorityQueue<Pair> q= new PriorityQueue<>((a,b)->b.x-a.x);
  
          private int find(int u){
              if(par[u]==u) return u;
              par[u]= find(par[u]);
              return par[u];
          }
  
          private boolean union(int u, int v){
              u= find(u); v= find(v);
              if(u==v) return false;
              if(size[u]>size[v]){
                  int temp= u; u=v; v= temp;
              }
              par[u]=v;
              size[v]+= size[u];
              return true;
          }
          private boolean already(int u, int v){
              return find(u)==find(v);
          }
  
          // Queue<Pair> q;
          boolean[][] force;
          char[][] a;
          int[] di= new int[]{1,-1,0,0};
          int[] dj= new int[]{0,0,1,-1};
          int n,m;
          public void solveA(int t){
              // q= new ArrayList<>();
              n= in.nextInt(); m= in.nextInt();
              int il=-1, jl=-1;
              force= new boolean[n][m];
              a= new char[n][m];
              for(int i=0;i<n;i++){
                  String temp= in.nextToken();
                  for(int j=0;j<temp.length();j++) {
                      a[i][j]= temp.charAt(j);
                      if(a[i][j]=='L') {
                          il=i; jl=j; 
                      }
                  }
              }
  
              dfs(il,jl);
              for(int i=0;i<n;i++){
                  for(int j=0;j<m;j++){
                      if(a[i][j]=='.' && force[i][j]) a[i][j]='+';
                      out.print(a[i][j]);
                  }
                  out.println();
              }
          }
  
          private void dfs(int i, int j){
              if(force[i][j]) return;
              force[i][j]= true;
              for(int k=0;k<4;k++){
                  int ni= i+di[k], nj= j+dj[k];
                  if(ni>=0 && ni<n && nj>=0 && nj<m && !force[ni][nj] && a[ni][nj]=='.'){
                      if(canForce(ni,nj)){
                          dfs(ni,nj);
                      }
                  }
              }
          }
  
          private boolean canForce(int i, int j){
              int res=0;
              for(int k=0;k<4;k++){
                  int ni= i+di[k], nj= j+dj[k];
                  if(ni>=0 && ni<n && nj>=0 && nj<m && !force[ni][nj] && a[ni][nj]=='.') res++;
              }
              // if(i==0 && j==1) out.println(res);
              return res<=1;
          }
  
          
  
          static class Node implements Comparable<Node>{
              char op;
              int s;
              public Node (char op, int s) {
                  this.op= op;
                  this.s= s;
              }
              @Override
              public int compareTo(Node o) {
                  if (this.s==o.s) return (int)(this.op-o.op);
                  return this.s-o.s;
              }
  
          }
  
          private long distance(Point p1, Point p2) {
              long x= p1.x-p2.x, y= p1.y-p2.y;
              return x*x+y*y;
          }
  
  
          private boolean eqPoint(Point p1, Point p2){
              return p1.x==p2.x && p1.y==p2.y;
          }
  
          private double polarAngle(Point p1, Point p2) {
              // p1 -> p2
              if (p1.x==p2.x) return pi/2;
              else if (p1.y==p2.y){
                  if(p1.x<p2.x) return 0;
                  else return pi;
              }
              else {
                  double y= (double)p2.y-(double)p1.y;
                  double x= (double)p2.x-(double)p1.x;
                  BigDecimal alpha1= new BigDecimal(y);
                  BigDecimal alpha2= new BigDecimal(x);
                  BigDecimal val= alpha1.divide(alpha2);
  
                  double angle= Math.atan(val.doubleValue());
                  if (angle<0) angle+= pi;
                  out.println("angle: "+angle);
                  return angle;
              }
          }
  
          private boolean isRightTurn(Point p1, Point p2, Point p3){
              Vector v1= new Vector(p1,p2), v2= new Vector(p1,p3);
              if(crossProd(v1,v2)<0) return true;
              else return false;
          }
  
          private long crossProd(Vector v1, Vector v2){
              //x1*y2-x2*y1
              return v1.x*v2.y - v2.x*v1.y;
          }
  
          static class PointAngle implements Comparable<PointAngle>{
              Point p;
              double angle;
              long dis;
              public PointAngle(Point p, double angle, long dis) {
                  this.p= p;
                  this.angle= angle;
                  this.dis= dis;
  
              }
  
              @Override
              public int compareTo(PointAngle o) {
                  double dif= this.angle-o.angle;
                  if (dif <0) return -1;
                  else if(dif >0) return 1;
                  else {
                      long dif2r= this.dis-o.dis;
                      long dif2l= o.dis-this.dis;
  
                      if (base.x < this.p.x) return intDif(dif2r);
                      else return intDif(dif2l); 
                      
                  }
              }
  
              private int intDif(long a){
                  if (a>0) return 1;
                  else if(a<0) return -1;
                  else return 0;
              }
          }
  
  
      
          
          public long _gcd(long a,  long b)
          {
  
              if(b == 0) {
                  return a;
              }
              else {
                  return _gcd(b, a % b);
              }
          }
          public long _lcm(long a, long b){
              return (a*b)/_gcd(a,b);
          }
  
      }
  
  
      // static class SEG {
  
      //     Pair[] segtree;
          
      //     public SEG(int n){
              
      //         segtree= new Pair[4*n];
      //         Arrays.fill(segtree, new Pair(-1,Long.MAX_VALUE));
      //     }
      //     // void buildTree(int l, int r, int index) {
      //     //     if (l == r) {
      //     //         segtree[index].y = a[l];
      //     //         return;
      //     //     }
      //     //     int mid = (l + r) / 2;
      //     //     buildTree(l, mid, 2 * index + 1);
      //     //     buildTree(mid + 1, r, 2 * index + 2);
      //     //     segtree[index].y = Math.min(segtree[2 * index + 1].y, segtree[2 * index + 2].y);
      //     // }
          
      //     void update(int l, int r, int index, int pos, Pair val) {
      //         if (l == r) {
      //             segtree[index] = val;
      //             return;
      //         }
      //         int mid = (l + r) / 2;
      //         if (pos <= mid) update(l, mid, 2 * index + 1, pos, val);
      //         else update(mid + 1, r, 2 * index + 2, pos, val);
      //         if(segtree[2 * index + 1].y < segtree[2 * index + 2].y){
      //             segtree[index]= segtree[2 * index + 1];
      //         }
      //         else {
      //             segtree[index]= segtree[2 * index + 2];
      //         }
      //     }
          
      //     // Pair query(int l, int r, int from, int to, int index) {
      //     //     if (from <= l && r <= to)
      //     //         return segtree[index];
      //     //     if (r < from | to < l)
      //     //         return 0;
      //     //     int mid = (l + r) / 2;
      //     //     Pair left= query(l, mid, from, to, 2 * index + 1);
      //     //     Pair right= query(mid + 1, r, from, to, 2 * index + 2);
      //     //     if(left.y < right.y) return left;
      //     //     else return right;
              
      //     // }
          
          
      // }
  
      static class Venice{
          public Map<Long,Long> m= new HashMap<>();
          public long base=0;
          public long totalValue=0;
          private int M= 1000000007;
  
          private long addMod(long a, long b){
              a+=b;
              if(a>=M) a-=M;
              return a;
          }
  
          public void reset(){
              m= new HashMap<>();
              base=0;
              totalValue=0;
          }
          public void update(long add){
              base= base+ add;
          }
          public void add(long key, long val){
              long newKey= key-base;
              m.put(newKey, addMod(m.getOrDefault(newKey,(long)0),val));
          }
      }
  
  
  
      static class Tuple implements Comparable<Tuple>{
          int x, y, z;
          public Tuple(int x, int y, int z){
              this.x= x;
              this.y= y;
              this.z=z;
          }
          @Override
          public int compareTo(Tuple o){
              return this.z-o.z;
          }
      }
  
      static class Point implements Comparable<Point>{
          public long x;
          public long y;
          public Point(long x, long y){
              this.x= x;
              this.y= y;
          }
  
          @Override
          public int compareTo(Point o) {
              if(this.y!=o.y) return (int)(this.y-o.y);
              return (int)(this.x-o.x);
          }
      }
  
      static class Vector {
          public long x;
          public long y;
  
          // p1 -> p2
          public Vector(Point p1, Point p2){
              this.x= p2.x-p1.x;
              this.y= p2.y-p1.y;
          }
      }
  
      static class Pair implements Comparable<Pair>{
          public int x;
          public int y;
          public Pair(int x, int y){
              this.x= x;
              this.y= y;
          }
  
          @Override
          public int compareTo(Pair o) {
              if(this.x!=o.x) return this.x-o.x;
              return (int)(this.y-o.y);
          }
      }
  
      // public static class compareL implements Comparator<Tuple>{
      //     @Override
      //     public int compare(Tuple t1, Tuple t2) {
      //         return t2.l - t1.l;
      //     }
      // }
  
      // fast input reader class;
      static class InputReader {
          BufferedReader br;
          StringTokenizer st;
  
          public InputReader(InputStream stream) {
              br = new BufferedReader(new InputStreamReader(stream));
          }
  
          public String nextToken() {
              while (st == null || !st.hasMoreTokens()) {
                  String line = null;
                  try {
                      line = br.readLine();
                  } catch (IOException e) {
                      throw new RuntimeException(e);
                  }
                  if (line == null) {
                      return null;
                  }
                  st = new StringTokenizer(line);
              }
              return st.nextToken();
          }
  
          public int nextInt() {
              return Integer.parseInt(nextToken());
          }
          public double nextDouble(){
              return Double.parseDouble(nextToken());
          }
          public long nextLong(){
              return Long.parseLong(nextToken());
          }
          public int[] nextIntArr(int n){
              int[] arr= new int[n];
              for(int i=0;i<n;i++) arr[i]= nextInt();
              return arr;
          }
          public long[] nextLongArr(int n){
              long[] arr= new long[n];
              for(int i=0;i<n;i++) arr[i]= nextLong();
              return arr;
          }
          public List<Integer> nextIntList(int n){
              List<Integer> arr= new ArrayList<>();
              for(int i=0;i<n;i++) arr.add(nextInt());
              return arr;
          }
          public int[][] nextIntMatArr(int n, int m){
              int[][] mat= new int[n][m];
              for(int i=0;i<n;i++) for(int j=0;j<m;j++) mat[i][j]= nextInt();
              return mat;
          }
          public List<List<Integer>> nextIntMatList(int n, int m){
              List<List<Integer>> mat= new ArrayList<>();
              for(int i=0;i<n;i++){
                  List<Integer> temp= new ArrayList<>();
                  for(int j=0;j<m;j++) temp.add(nextInt());
                  mat.add(temp);
              }
              return mat;
          }
          public char[] nextStringCharArr(){
              return nextToken().toCharArray();
          }
      }
  
      static class CustomFileReader{
          String path="";
          Scanner sc;
          public CustomFileReader(String path){
              this.path=path;
              try{
                  sc= new Scanner(new File(path));
              }
              catch(Exception e){}
          }
          public String nextLine(){
              return sc.nextLine();
          }
          public int[] nextIntArrLine(){
              String line= sc.nextLine();
              String[] part= line.split("[\\s+]");
              int[] res= new int[part.length];
              for(int i=0;i<res.length;i++) res[i]= Integer.parseInt(part[i]);
              return res;
          }
      }
  }