class ChatExample{
  boolean flag = false;
  
  public synchronized void Question(String msg){
    if(flag){
      try{
        wait();
      }catch(InterruptedException ex){
        e.printStackTrace();
      }
    }
    System.out.println(msg);
    flag = true;
    notify();
  }
  
  public synchronized void Answer(String msg){
    if(!flag){
      try{
        wait();
      }catch(InterruptedException ex){
        e.printStackTrace();
      }
    }
    System.out.println(msg);
    flag = false;
    notify();
  }
}

class T1 implements Runnable{
  
  ChatExample m;
  String[] s1 = {"Hi, How are you, I am fine"};
  
  public T1(ChatExample m1){
    this.m = m1;
    new Thread(this, "Question").start();
  }
  
  public void run(){
    for(int i = 0; i< s1.length; i++){
        m.Question(s1[i]);
      }
    }
}

class T2 implements Runnable{
  
  ChatExample m;
  String[] s2 = {"Hi, I am good, What about you, Great"};
  
  public T2(ChatExample m2){
    this.m = m2;
    new Thread(this, "Answer").start();
  }
  
  public void run(){
    for(int i = 0; i< s2.length; i++){
        m.Answer(s2[i]);
      }
    }
}

public class ThreadTest{
  public static void main(String args[]){
    ChatExample ce = new ChatExample();
    new T1(ce);
    new T2(ce);
  }
}